ActivityManagerService.java revision a0995ab8212a26945fe377346e110fa9a6e663dd
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.UsageStats;
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);
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(new File(
2204                systemDir, "batterystats.bin").toString(), mHandler);
2205        mBatteryStatsService.getActiveStatistics().readLocked();
2206        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2207        mOnBattery = DEBUG_POWER ? true
2208                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2209        mBatteryStatsService.getActiveStatistics().setCallback(this);
2210
2211        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2212
2213        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2214
2215        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2216
2217        // User 0 is the first and only user that runs at boot.
2218        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2219        mUserLru.add(Integer.valueOf(0));
2220        updateStartedUserArrayLocked();
2221
2222        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2223            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2224
2225        mConfiguration.setToDefaults();
2226        mConfiguration.setLocale(Locale.getDefault());
2227
2228        mConfigurationSeq = mConfiguration.seq = 1;
2229        mProcessCpuTracker.init();
2230
2231        mHasRecents = mContext.getResources().getBoolean(
2232                com.android.internal.R.bool.config_hasRecents);
2233
2234        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2235        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2236        mStackSupervisor = new ActivityStackSupervisor(this);
2237        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2238
2239        mProcessCpuThread = new Thread("CpuTracker") {
2240            @Override
2241            public void run() {
2242                while (true) {
2243                    try {
2244                        try {
2245                            synchronized(this) {
2246                                final long now = SystemClock.uptimeMillis();
2247                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2248                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2249                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2250                                //        + ", write delay=" + nextWriteDelay);
2251                                if (nextWriteDelay < nextCpuDelay) {
2252                                    nextCpuDelay = nextWriteDelay;
2253                                }
2254                                if (nextCpuDelay > 0) {
2255                                    mProcessCpuMutexFree.set(true);
2256                                    this.wait(nextCpuDelay);
2257                                }
2258                            }
2259                        } catch (InterruptedException e) {
2260                        }
2261                        updateCpuStatsNow();
2262                    } catch (Exception e) {
2263                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2264                    }
2265                }
2266            }
2267        };
2268
2269        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2270
2271        Watchdog.getInstance().addMonitor(this);
2272        Watchdog.getInstance().addThread(mHandler);
2273    }
2274
2275    public void setSystemServiceManager(SystemServiceManager mgr) {
2276        mSystemServiceManager = mgr;
2277    }
2278
2279    private void start() {
2280        Process.removeAllProcessGroups();
2281        mProcessCpuThread.start();
2282
2283        mBatteryStatsService.publish(mContext);
2284        mAppOpsService.publish(mContext);
2285        Slog.d("AppOps", "AppOpsService published");
2286        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2287    }
2288
2289    public void initPowerManagement() {
2290        mStackSupervisor.initPowerManagement();
2291        mBatteryStatsService.initPowerManagement();
2292    }
2293
2294    @Override
2295    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2296            throws RemoteException {
2297        if (code == SYSPROPS_TRANSACTION) {
2298            // We need to tell all apps about the system property change.
2299            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2300            synchronized(this) {
2301                final int NP = mProcessNames.getMap().size();
2302                for (int ip=0; ip<NP; ip++) {
2303                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2304                    final int NA = apps.size();
2305                    for (int ia=0; ia<NA; ia++) {
2306                        ProcessRecord app = apps.valueAt(ia);
2307                        if (app.thread != null) {
2308                            procs.add(app.thread.asBinder());
2309                        }
2310                    }
2311                }
2312            }
2313
2314            int N = procs.size();
2315            for (int i=0; i<N; i++) {
2316                Parcel data2 = Parcel.obtain();
2317                try {
2318                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2319                } catch (RemoteException e) {
2320                }
2321                data2.recycle();
2322            }
2323        }
2324        try {
2325            return super.onTransact(code, data, reply, flags);
2326        } catch (RuntimeException e) {
2327            // The activity manager only throws security exceptions, so let's
2328            // log all others.
2329            if (!(e instanceof SecurityException)) {
2330                Slog.wtf(TAG, "Activity Manager Crash", e);
2331            }
2332            throw e;
2333        }
2334    }
2335
2336    void updateCpuStats() {
2337        final long now = SystemClock.uptimeMillis();
2338        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2339            return;
2340        }
2341        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2342            synchronized (mProcessCpuThread) {
2343                mProcessCpuThread.notify();
2344            }
2345        }
2346    }
2347
2348    void updateCpuStatsNow() {
2349        synchronized (mProcessCpuThread) {
2350            mProcessCpuMutexFree.set(false);
2351            final long now = SystemClock.uptimeMillis();
2352            boolean haveNewCpuStats = false;
2353
2354            if (MONITOR_CPU_USAGE &&
2355                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2356                mLastCpuTime.set(now);
2357                haveNewCpuStats = true;
2358                mProcessCpuTracker.update();
2359                //Slog.i(TAG, mProcessCpu.printCurrentState());
2360                //Slog.i(TAG, "Total CPU usage: "
2361                //        + mProcessCpu.getTotalCpuPercent() + "%");
2362
2363                // Slog the cpu usage if the property is set.
2364                if ("true".equals(SystemProperties.get("events.cpu"))) {
2365                    int user = mProcessCpuTracker.getLastUserTime();
2366                    int system = mProcessCpuTracker.getLastSystemTime();
2367                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2368                    int irq = mProcessCpuTracker.getLastIrqTime();
2369                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2370                    int idle = mProcessCpuTracker.getLastIdleTime();
2371
2372                    int total = user + system + iowait + irq + softIrq + idle;
2373                    if (total == 0) total = 1;
2374
2375                    EventLog.writeEvent(EventLogTags.CPU,
2376                            ((user+system+iowait+irq+softIrq) * 100) / total,
2377                            (user * 100) / total,
2378                            (system * 100) / total,
2379                            (iowait * 100) / total,
2380                            (irq * 100) / total,
2381                            (softIrq * 100) / total);
2382                }
2383            }
2384
2385            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2386            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2387            synchronized(bstats) {
2388                synchronized(mPidsSelfLocked) {
2389                    if (haveNewCpuStats) {
2390                        if (mOnBattery) {
2391                            int perc = bstats.startAddingCpuLocked();
2392                            int totalUTime = 0;
2393                            int totalSTime = 0;
2394                            final int N = mProcessCpuTracker.countStats();
2395                            for (int i=0; i<N; i++) {
2396                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2397                                if (!st.working) {
2398                                    continue;
2399                                }
2400                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2401                                int otherUTime = (st.rel_utime*perc)/100;
2402                                int otherSTime = (st.rel_stime*perc)/100;
2403                                totalUTime += otherUTime;
2404                                totalSTime += otherSTime;
2405                                if (pr != null) {
2406                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2407                                    if (ps == null || !ps.isActive()) {
2408                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2409                                                pr.info.uid, pr.processName);
2410                                    }
2411                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2412                                            st.rel_stime-otherSTime);
2413                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2414                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2415                                } else {
2416                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2417                                    if (ps == null || !ps.isActive()) {
2418                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2419                                                bstats.mapUid(st.uid), st.name);
2420                                    }
2421                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2422                                            st.rel_stime-otherSTime);
2423                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2424                                }
2425                            }
2426                            bstats.finishAddingCpuLocked(perc, totalUTime,
2427                                    totalSTime, cpuSpeedTimes);
2428                        }
2429                    }
2430                }
2431
2432                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2433                    mLastWriteTime = now;
2434                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2435                }
2436            }
2437        }
2438    }
2439
2440    @Override
2441    public void batteryNeedsCpuUpdate() {
2442        updateCpuStatsNow();
2443    }
2444
2445    @Override
2446    public void batteryPowerChanged(boolean onBattery) {
2447        // When plugging in, update the CPU stats first before changing
2448        // the plug state.
2449        updateCpuStatsNow();
2450        synchronized (this) {
2451            synchronized(mPidsSelfLocked) {
2452                mOnBattery = DEBUG_POWER ? true : onBattery;
2453            }
2454        }
2455    }
2456
2457    /**
2458     * Initialize the application bind args. These are passed to each
2459     * process when the bindApplication() IPC is sent to the process. They're
2460     * lazily setup to make sure the services are running when they're asked for.
2461     */
2462    private HashMap<String, IBinder> getCommonServicesLocked() {
2463        if (mAppBindArgs == null) {
2464            mAppBindArgs = new HashMap<String, IBinder>();
2465
2466            // Setup the application init args
2467            mAppBindArgs.put("package", ServiceManager.getService("package"));
2468            mAppBindArgs.put("window", ServiceManager.getService("window"));
2469            mAppBindArgs.put(Context.ALARM_SERVICE,
2470                    ServiceManager.getService(Context.ALARM_SERVICE));
2471        }
2472        return mAppBindArgs;
2473    }
2474
2475    final void setFocusedActivityLocked(ActivityRecord r) {
2476        if (mFocusedActivity != r) {
2477            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2478            mFocusedActivity = r;
2479            if (r.task != null && r.task.voiceInteractor != null) {
2480                startRunningVoiceLocked();
2481            } else {
2482                finishRunningVoiceLocked();
2483            }
2484            mStackSupervisor.setFocusedStack(r);
2485            if (r != null) {
2486                mWindowManager.setFocusedApp(r.appToken, true);
2487            }
2488            applyUpdateLockStateLocked(r);
2489        }
2490    }
2491
2492    final void clearFocusedActivity(ActivityRecord r) {
2493        if (mFocusedActivity == r) {
2494            mFocusedActivity = null;
2495        }
2496    }
2497
2498    @Override
2499    public void setFocusedStack(int stackId) {
2500        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2501        synchronized (ActivityManagerService.this) {
2502            ActivityStack stack = mStackSupervisor.getStack(stackId);
2503            if (stack != null) {
2504                ActivityRecord r = stack.topRunningActivityLocked(null);
2505                if (r != null) {
2506                    setFocusedActivityLocked(r);
2507                }
2508            }
2509        }
2510    }
2511
2512    @Override
2513    public void notifyActivityDrawn(IBinder token) {
2514        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2515        synchronized (this) {
2516            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2517            if (r != null) {
2518                r.task.stack.notifyActivityDrawnLocked(r);
2519            }
2520        }
2521    }
2522
2523    final void applyUpdateLockStateLocked(ActivityRecord r) {
2524        // Modifications to the UpdateLock state are done on our handler, outside
2525        // the activity manager's locks.  The new state is determined based on the
2526        // state *now* of the relevant activity record.  The object is passed to
2527        // the handler solely for logging detail, not to be consulted/modified.
2528        final boolean nextState = r != null && r.immersive;
2529        mHandler.sendMessage(
2530                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2531    }
2532
2533    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2534        Message msg = Message.obtain();
2535        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2536        msg.obj = r.task.askedCompatMode ? null : r;
2537        mHandler.sendMessage(msg);
2538    }
2539
2540    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2541            String what, Object obj, ProcessRecord srcApp) {
2542        app.lastActivityTime = now;
2543
2544        if (app.activities.size() > 0) {
2545            // Don't want to touch dependent processes that are hosting activities.
2546            return index;
2547        }
2548
2549        int lrui = mLruProcesses.lastIndexOf(app);
2550        if (lrui < 0) {
2551            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2552                    + what + " " + obj + " from " + srcApp);
2553            return index;
2554        }
2555
2556        if (lrui >= index) {
2557            // Don't want to cause this to move dependent processes *back* in the
2558            // list as if they were less frequently used.
2559            return index;
2560        }
2561
2562        if (lrui >= mLruProcessActivityStart) {
2563            // Don't want to touch dependent processes that are hosting activities.
2564            return index;
2565        }
2566
2567        mLruProcesses.remove(lrui);
2568        if (index > 0) {
2569            index--;
2570        }
2571        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2572                + " in LRU list: " + app);
2573        mLruProcesses.add(index, app);
2574        return index;
2575    }
2576
2577    final void removeLruProcessLocked(ProcessRecord app) {
2578        int lrui = mLruProcesses.lastIndexOf(app);
2579        if (lrui >= 0) {
2580            if (lrui <= mLruProcessActivityStart) {
2581                mLruProcessActivityStart--;
2582            }
2583            if (lrui <= mLruProcessServiceStart) {
2584                mLruProcessServiceStart--;
2585            }
2586            mLruProcesses.remove(lrui);
2587        }
2588    }
2589
2590    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2591            ProcessRecord client) {
2592        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2593                || app.treatLikeActivity;
2594        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2595        if (!activityChange && hasActivity) {
2596            // The process has activities, so we are only allowing activity-based adjustments
2597            // to move it.  It should be kept in the front of the list with other
2598            // processes that have activities, and we don't want those to change their
2599            // order except due to activity operations.
2600            return;
2601        }
2602
2603        mLruSeq++;
2604        final long now = SystemClock.uptimeMillis();
2605        app.lastActivityTime = now;
2606
2607        // First a quick reject: if the app is already at the position we will
2608        // put it, then there is nothing to do.
2609        if (hasActivity) {
2610            final int N = mLruProcesses.size();
2611            if (N > 0 && mLruProcesses.get(N-1) == app) {
2612                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2613                return;
2614            }
2615        } else {
2616            if (mLruProcessServiceStart > 0
2617                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2618                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2619                return;
2620            }
2621        }
2622
2623        int lrui = mLruProcesses.lastIndexOf(app);
2624
2625        if (app.persistent && lrui >= 0) {
2626            // We don't care about the position of persistent processes, as long as
2627            // they are in the list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2629            return;
2630        }
2631
2632        /* In progress: compute new position first, so we can avoid doing work
2633           if the process is not actually going to move.  Not yet working.
2634        int addIndex;
2635        int nextIndex;
2636        boolean inActivity = false, inService = false;
2637        if (hasActivity) {
2638            // Process has activities, put it at the very tipsy-top.
2639            addIndex = mLruProcesses.size();
2640            nextIndex = mLruProcessServiceStart;
2641            inActivity = true;
2642        } else if (hasService) {
2643            // Process has services, put it at the top of the service list.
2644            addIndex = mLruProcessActivityStart;
2645            nextIndex = mLruProcessServiceStart;
2646            inActivity = true;
2647            inService = true;
2648        } else  {
2649            // Process not otherwise of interest, it goes to the top of the non-service area.
2650            addIndex = mLruProcessServiceStart;
2651            if (client != null) {
2652                int clientIndex = mLruProcesses.lastIndexOf(client);
2653                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2654                        + app);
2655                if (clientIndex >= 0 && addIndex > clientIndex) {
2656                    addIndex = clientIndex;
2657                }
2658            }
2659            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2660        }
2661
2662        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2663                + mLruProcessActivityStart + "): " + app);
2664        */
2665
2666        if (lrui >= 0) {
2667            if (lrui < mLruProcessActivityStart) {
2668                mLruProcessActivityStart--;
2669            }
2670            if (lrui < mLruProcessServiceStart) {
2671                mLruProcessServiceStart--;
2672            }
2673            /*
2674            if (addIndex > lrui) {
2675                addIndex--;
2676            }
2677            if (nextIndex > lrui) {
2678                nextIndex--;
2679            }
2680            */
2681            mLruProcesses.remove(lrui);
2682        }
2683
2684        /*
2685        mLruProcesses.add(addIndex, app);
2686        if (inActivity) {
2687            mLruProcessActivityStart++;
2688        }
2689        if (inService) {
2690            mLruProcessActivityStart++;
2691        }
2692        */
2693
2694        int nextIndex;
2695        if (hasActivity) {
2696            final int N = mLruProcesses.size();
2697            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2698                // Process doesn't have activities, but has clients with
2699                // activities...  move it up, but one below the top (the top
2700                // should always have a real activity).
2701                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2702                mLruProcesses.add(N-1, app);
2703                // To keep it from spamming the LRU list (by making a bunch of clients),
2704                // we will push down any other entries owned by the app.
2705                final int uid = app.info.uid;
2706                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2707                    ProcessRecord subProc = mLruProcesses.get(i);
2708                    if (subProc.info.uid == uid) {
2709                        // We want to push this one down the list.  If the process after
2710                        // it is for the same uid, however, don't do so, because we don't
2711                        // want them internally to be re-ordered.
2712                        if (mLruProcesses.get(i-1).info.uid != uid) {
2713                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2714                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2715                            ProcessRecord tmp = mLruProcesses.get(i);
2716                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2717                            mLruProcesses.set(i-1, tmp);
2718                            i--;
2719                        }
2720                    } else {
2721                        // A gap, we can stop here.
2722                        break;
2723                    }
2724                }
2725            } else {
2726                // Process has activities, put it at the very tipsy-top.
2727                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2728                mLruProcesses.add(app);
2729            }
2730            nextIndex = mLruProcessServiceStart;
2731        } else if (hasService) {
2732            // Process has services, put it at the top of the service list.
2733            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2734            mLruProcesses.add(mLruProcessActivityStart, app);
2735            nextIndex = mLruProcessServiceStart;
2736            mLruProcessActivityStart++;
2737        } else  {
2738            // Process not otherwise of interest, it goes to the top of the non-service area.
2739            int index = mLruProcessServiceStart;
2740            if (client != null) {
2741                // If there is a client, don't allow the process to be moved up higher
2742                // in the list than that client.
2743                int clientIndex = mLruProcesses.lastIndexOf(client);
2744                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2745                        + " when updating " + app);
2746                if (clientIndex <= lrui) {
2747                    // Don't allow the client index restriction to push it down farther in the
2748                    // list than it already is.
2749                    clientIndex = lrui;
2750                }
2751                if (clientIndex >= 0 && index > clientIndex) {
2752                    index = clientIndex;
2753                }
2754            }
2755            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2756            mLruProcesses.add(index, app);
2757            nextIndex = index-1;
2758            mLruProcessActivityStart++;
2759            mLruProcessServiceStart++;
2760        }
2761
2762        // If the app is currently using a content provider or service,
2763        // bump those processes as well.
2764        for (int j=app.connections.size()-1; j>=0; j--) {
2765            ConnectionRecord cr = app.connections.valueAt(j);
2766            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2767                    && cr.binding.service.app != null
2768                    && cr.binding.service.app.lruSeq != mLruSeq
2769                    && !cr.binding.service.app.persistent) {
2770                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2771                        "service connection", cr, app);
2772            }
2773        }
2774        for (int j=app.conProviders.size()-1; j>=0; j--) {
2775            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2776            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2777                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2778                        "provider reference", cpr, app);
2779            }
2780        }
2781    }
2782
2783    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2784        if (uid == Process.SYSTEM_UID) {
2785            // The system gets to run in any process.  If there are multiple
2786            // processes with the same uid, just pick the first (this
2787            // should never happen).
2788            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2789            if (procs == null) return null;
2790            final int N = procs.size();
2791            for (int i = 0; i < N; i++) {
2792                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2793            }
2794        }
2795        ProcessRecord proc = mProcessNames.get(processName, uid);
2796        if (false && proc != null && !keepIfLarge
2797                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2798                && proc.lastCachedPss >= 4000) {
2799            // Turn this condition on to cause killing to happen regularly, for testing.
2800            if (proc.baseProcessTracker != null) {
2801                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2802            }
2803            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2804                    + "k from cached");
2805        } else if (proc != null && !keepIfLarge
2806                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2807                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2808            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2809            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2810                if (proc.baseProcessTracker != null) {
2811                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2812                }
2813                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2814                        + "k from cached");
2815            }
2816        }
2817        return proc;
2818    }
2819
2820    void ensurePackageDexOpt(String packageName) {
2821        IPackageManager pm = AppGlobals.getPackageManager();
2822        try {
2823            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2824                mDidDexOpt = true;
2825            }
2826        } catch (RemoteException e) {
2827        }
2828    }
2829
2830    boolean isNextTransitionForward() {
2831        int transit = mWindowManager.getPendingAppTransition();
2832        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_OPEN
2834                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2835    }
2836
2837    final ProcessRecord startProcessLocked(String processName,
2838            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2839            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2840            boolean isolated, boolean keepIfLarge) {
2841        ProcessRecord app;
2842        if (!isolated) {
2843            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2844        } else {
2845            // If this is an isolated process, it can't re-use an existing process.
2846            app = null;
2847        }
2848        // We don't have to do anything more if:
2849        // (1) There is an existing application record; and
2850        // (2) The caller doesn't think it is dead, OR there is no thread
2851        //     object attached to it so we know it couldn't have crashed; and
2852        // (3) There is a pid assigned to it, so it is either starting or
2853        //     already running.
2854        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2855                + " app=" + app + " knownToBeDead=" + knownToBeDead
2856                + " thread=" + (app != null ? app.thread : null)
2857                + " pid=" + (app != null ? app.pid : -1));
2858        if (app != null && app.pid > 0) {
2859            if (!knownToBeDead || app.thread == null) {
2860                // We already have the app running, or are waiting for it to
2861                // come up (we have a pid but not yet its thread), so keep it.
2862                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2863                // If this is a new package in the process, add the package to the list
2864                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2865                return app;
2866            }
2867
2868            // An application record is attached to a previous process,
2869            // clean it up now.
2870            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2871            Process.killProcessGroup(app.info.uid, app.pid);
2872            handleAppDiedLocked(app, true, true);
2873        }
2874
2875        String hostingNameStr = hostingName != null
2876                ? hostingName.flattenToShortString() : null;
2877
2878        if (!isolated) {
2879            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2880                // If we are in the background, then check to see if this process
2881                // is bad.  If so, we will just silently fail.
2882                if (mBadProcesses.get(info.processName, info.uid) != null) {
2883                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2884                            + "/" + info.processName);
2885                    return null;
2886                }
2887            } else {
2888                // When the user is explicitly starting a process, then clear its
2889                // crash count so that we won't make it bad until they see at
2890                // least one crash dialog again, and make the process good again
2891                // if it had been bad.
2892                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2893                        + "/" + info.processName);
2894                mProcessCrashTimes.remove(info.processName, info.uid);
2895                if (mBadProcesses.get(info.processName, info.uid) != null) {
2896                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2897                            UserHandle.getUserId(info.uid), info.uid,
2898                            info.processName);
2899                    mBadProcesses.remove(info.processName, info.uid);
2900                    if (app != null) {
2901                        app.bad = false;
2902                    }
2903                }
2904            }
2905        }
2906
2907        if (app == null) {
2908            app = newProcessRecordLocked(info, processName, isolated);
2909            if (app == null) {
2910                Slog.w(TAG, "Failed making new process record for "
2911                        + processName + "/" + info.uid + " isolated=" + isolated);
2912                return null;
2913            }
2914            mProcessNames.put(processName, app.uid, app);
2915            if (isolated) {
2916                mIsolatedProcesses.put(app.uid, app);
2917            }
2918        } else {
2919            // If this is a new package in the process, add the package to the list
2920            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2921        }
2922
2923        // If the system is not ready yet, then hold off on starting this
2924        // process until it is.
2925        if (!mProcessesReady
2926                && !isAllowedWhileBooting(info)
2927                && !allowWhileBooting) {
2928            if (!mProcessesOnHold.contains(app)) {
2929                mProcessesOnHold.add(app);
2930            }
2931            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2932            return app;
2933        }
2934
2935        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2936        return (app.pid != 0) ? app : null;
2937    }
2938
2939    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2940        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2941    }
2942
2943    private final void startProcessLocked(ProcessRecord app,
2944            String hostingType, String hostingNameStr, String abiOverride) {
2945        if (app.pid > 0 && app.pid != MY_PID) {
2946            synchronized (mPidsSelfLocked) {
2947                mPidsSelfLocked.remove(app.pid);
2948                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2949            }
2950            app.setPid(0);
2951        }
2952
2953        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2954                "startProcessLocked removing on hold: " + app);
2955        mProcessesOnHold.remove(app);
2956
2957        updateCpuStats();
2958
2959        try {
2960            int uid = app.uid;
2961
2962            int[] gids = null;
2963            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2964            if (!app.isolated) {
2965                int[] permGids = null;
2966                try {
2967                    final PackageManager pm = mContext.getPackageManager();
2968                    permGids = pm.getPackageGids(app.info.packageName);
2969
2970                    if (Environment.isExternalStorageEmulated()) {
2971                        if (pm.checkPermission(
2972                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2973                                app.info.packageName) == PERMISSION_GRANTED) {
2974                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2975                        } else {
2976                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2977                        }
2978                    }
2979                } catch (PackageManager.NameNotFoundException e) {
2980                    Slog.w(TAG, "Unable to retrieve gids", e);
2981                }
2982
2983                /*
2984                 * Add shared application and profile GIDs so applications can share some
2985                 * resources like shared libraries and access user-wide resources
2986                 */
2987                if (permGids == null) {
2988                    gids = new int[2];
2989                } else {
2990                    gids = new int[permGids.length + 2];
2991                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2992                }
2993                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2994                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2995            }
2996            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2997                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2998                        && mTopComponent != null
2999                        && app.processName.equals(mTopComponent.getPackageName())) {
3000                    uid = 0;
3001                }
3002                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3003                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3004                    uid = 0;
3005                }
3006            }
3007            int debugFlags = 0;
3008            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3009                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3010                // Also turn on CheckJNI for debuggable apps. It's quite
3011                // awkward to turn on otherwise.
3012                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3013            }
3014            // Run the app in safe mode if its manifest requests so or the
3015            // system is booted in safe mode.
3016            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3017                mSafeMode == true) {
3018                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3019            }
3020            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3021                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3022            }
3023            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3024                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3025            }
3026            if ("1".equals(SystemProperties.get("debug.assert"))) {
3027                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3028            }
3029
3030            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3031            if (requiredAbi == null) {
3032                requiredAbi = Build.SUPPORTED_ABIS[0];
3033            }
3034
3035            // Start the process.  It will either succeed and return a result containing
3036            // the PID of the new process, or else throw a RuntimeException.
3037            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3038                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3039                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3040
3041            if (app.isolated) {
3042                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3043            }
3044            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3045
3046            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3047                    UserHandle.getUserId(uid), startResult.pid, uid,
3048                    app.processName, hostingType,
3049                    hostingNameStr != null ? hostingNameStr : "");
3050
3051            if (app.persistent) {
3052                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3053            }
3054
3055            StringBuilder buf = mStringBuilder;
3056            buf.setLength(0);
3057            buf.append("Start proc ");
3058            buf.append(app.processName);
3059            buf.append(" for ");
3060            buf.append(hostingType);
3061            if (hostingNameStr != null) {
3062                buf.append(" ");
3063                buf.append(hostingNameStr);
3064            }
3065            buf.append(": pid=");
3066            buf.append(startResult.pid);
3067            buf.append(" uid=");
3068            buf.append(uid);
3069            buf.append(" gids={");
3070            if (gids != null) {
3071                for (int gi=0; gi<gids.length; gi++) {
3072                    if (gi != 0) buf.append(", ");
3073                    buf.append(gids[gi]);
3074
3075                }
3076            }
3077            buf.append("}");
3078            if (requiredAbi != null) {
3079                buf.append(" abi=");
3080                buf.append(requiredAbi);
3081            }
3082            Slog.i(TAG, buf.toString());
3083            app.setPid(startResult.pid);
3084            app.usingWrapper = startResult.usingWrapper;
3085            app.removed = false;
3086            app.killedByAm = false;
3087            synchronized (mPidsSelfLocked) {
3088                this.mPidsSelfLocked.put(startResult.pid, app);
3089                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3090                msg.obj = app;
3091                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3092                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3093            }
3094        } catch (RuntimeException e) {
3095            // XXX do better error recovery.
3096            app.setPid(0);
3097            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3098            if (app.isolated) {
3099                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3100            }
3101            Slog.e(TAG, "Failure starting process " + app.processName, e);
3102        }
3103    }
3104
3105    void updateUsageStats(ActivityRecord component, boolean resumed) {
3106        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3107        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3108        if (resumed) {
3109            if (mUsageStatsService != null) {
3110                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3111                        System.currentTimeMillis(),
3112                        UsageStats.Event.MOVE_TO_FOREGROUND);
3113            }
3114            synchronized (stats) {
3115                stats.noteActivityResumedLocked(component.app.uid);
3116            }
3117        } else {
3118            if (mUsageStatsService != null) {
3119                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3120                        System.currentTimeMillis(),
3121                        UsageStats.Event.MOVE_TO_BACKGROUND);
3122            }
3123            synchronized (stats) {
3124                stats.noteActivityPausedLocked(component.app.uid);
3125            }
3126        }
3127    }
3128
3129    Intent getHomeIntent() {
3130        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3131        intent.setComponent(mTopComponent);
3132        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3133            intent.addCategory(Intent.CATEGORY_HOME);
3134        }
3135        return intent;
3136    }
3137
3138    boolean startHomeActivityLocked(int userId) {
3139        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3140                && mTopAction == null) {
3141            // We are running in factory test mode, but unable to find
3142            // the factory test app, so just sit around displaying the
3143            // error message and don't try to start anything.
3144            return false;
3145        }
3146        Intent intent = getHomeIntent();
3147        ActivityInfo aInfo =
3148            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3149        if (aInfo != null) {
3150            intent.setComponent(new ComponentName(
3151                    aInfo.applicationInfo.packageName, aInfo.name));
3152            // Don't do this if the home app is currently being
3153            // instrumented.
3154            aInfo = new ActivityInfo(aInfo);
3155            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3156            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3157                    aInfo.applicationInfo.uid, true);
3158            if (app == null || app.instrumentationClass == null) {
3159                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3160                mStackSupervisor.startHomeActivity(intent, aInfo);
3161            }
3162        }
3163
3164        return true;
3165    }
3166
3167    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3168        ActivityInfo ai = null;
3169        ComponentName comp = intent.getComponent();
3170        try {
3171            if (comp != null) {
3172                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3173            } else {
3174                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3175                        intent,
3176                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3177                            flags, userId);
3178
3179                if (info != null) {
3180                    ai = info.activityInfo;
3181                }
3182            }
3183        } catch (RemoteException e) {
3184            // ignore
3185        }
3186
3187        return ai;
3188    }
3189
3190    /**
3191     * Starts the "new version setup screen" if appropriate.
3192     */
3193    void startSetupActivityLocked() {
3194        // Only do this once per boot.
3195        if (mCheckedForSetup) {
3196            return;
3197        }
3198
3199        // We will show this screen if the current one is a different
3200        // version than the last one shown, and we are not running in
3201        // low-level factory test mode.
3202        final ContentResolver resolver = mContext.getContentResolver();
3203        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3204                Settings.Global.getInt(resolver,
3205                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3206            mCheckedForSetup = true;
3207
3208            // See if we should be showing the platform update setup UI.
3209            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3210            List<ResolveInfo> ris = mContext.getPackageManager()
3211                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3212
3213            // We don't allow third party apps to replace this.
3214            ResolveInfo ri = null;
3215            for (int i=0; ris != null && i<ris.size(); i++) {
3216                if ((ris.get(i).activityInfo.applicationInfo.flags
3217                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3218                    ri = ris.get(i);
3219                    break;
3220                }
3221            }
3222
3223            if (ri != null) {
3224                String vers = ri.activityInfo.metaData != null
3225                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3226                        : null;
3227                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3228                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3229                            Intent.METADATA_SETUP_VERSION);
3230                }
3231                String lastVers = Settings.Secure.getString(
3232                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3233                if (vers != null && !vers.equals(lastVers)) {
3234                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3235                    intent.setComponent(new ComponentName(
3236                            ri.activityInfo.packageName, ri.activityInfo.name));
3237                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3238                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3239                }
3240            }
3241        }
3242    }
3243
3244    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3245        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3246    }
3247
3248    void enforceNotIsolatedCaller(String caller) {
3249        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3250            throw new SecurityException("Isolated process not allowed to call " + caller);
3251        }
3252    }
3253
3254    @Override
3255    public int getFrontActivityScreenCompatMode() {
3256        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3257        synchronized (this) {
3258            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3259        }
3260    }
3261
3262    @Override
3263    public void setFrontActivityScreenCompatMode(int mode) {
3264        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3265                "setFrontActivityScreenCompatMode");
3266        synchronized (this) {
3267            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3268        }
3269    }
3270
3271    @Override
3272    public int getPackageScreenCompatMode(String packageName) {
3273        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3274        synchronized (this) {
3275            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3276        }
3277    }
3278
3279    @Override
3280    public void setPackageScreenCompatMode(String packageName, int mode) {
3281        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3282                "setPackageScreenCompatMode");
3283        synchronized (this) {
3284            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3285        }
3286    }
3287
3288    @Override
3289    public boolean getPackageAskScreenCompat(String packageName) {
3290        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3291        synchronized (this) {
3292            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3293        }
3294    }
3295
3296    @Override
3297    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3298        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3299                "setPackageAskScreenCompat");
3300        synchronized (this) {
3301            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3302        }
3303    }
3304
3305    private void dispatchProcessesChanged() {
3306        int N;
3307        synchronized (this) {
3308            N = mPendingProcessChanges.size();
3309            if (mActiveProcessChanges.length < N) {
3310                mActiveProcessChanges = new ProcessChangeItem[N];
3311            }
3312            mPendingProcessChanges.toArray(mActiveProcessChanges);
3313            mAvailProcessChanges.addAll(mPendingProcessChanges);
3314            mPendingProcessChanges.clear();
3315            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3316        }
3317
3318        int i = mProcessObservers.beginBroadcast();
3319        while (i > 0) {
3320            i--;
3321            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3322            if (observer != null) {
3323                try {
3324                    for (int j=0; j<N; j++) {
3325                        ProcessChangeItem item = mActiveProcessChanges[j];
3326                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3327                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3328                                    + item.pid + " uid=" + item.uid + ": "
3329                                    + item.foregroundActivities);
3330                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3331                                    item.foregroundActivities);
3332                        }
3333                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3334                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3335                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3336                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3337                        }
3338                    }
3339                } catch (RemoteException e) {
3340                }
3341            }
3342        }
3343        mProcessObservers.finishBroadcast();
3344    }
3345
3346    private void dispatchProcessDied(int pid, int uid) {
3347        int i = mProcessObservers.beginBroadcast();
3348        while (i > 0) {
3349            i--;
3350            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3351            if (observer != null) {
3352                try {
3353                    observer.onProcessDied(pid, uid);
3354                } catch (RemoteException e) {
3355                }
3356            }
3357        }
3358        mProcessObservers.finishBroadcast();
3359    }
3360
3361    @Override
3362    public final int startActivity(IApplicationThread caller, String callingPackage,
3363            Intent intent, String resolvedType, IBinder resultTo,
3364            String resultWho, int requestCode, int startFlags,
3365            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3366        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3367                resultWho, requestCode,
3368                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3369    }
3370
3371    @Override
3372    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3373            Intent intent, String resolvedType, IBinder resultTo,
3374            String resultWho, int requestCode, int startFlags,
3375            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3376        enforceNotIsolatedCaller("startActivity");
3377        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3378                false, ALLOW_FULL_ONLY, "startActivity", null);
3379        // TODO: Switch to user app stacks here.
3380        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3381                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3382                null, null, options, userId, null);
3383    }
3384
3385    @Override
3386    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3387            Intent intent, String resolvedType, IBinder resultTo,
3388            String resultWho, int requestCode, int startFlags, String profileFile,
3389            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3390        enforceNotIsolatedCaller("startActivityAndWait");
3391        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3392                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3393        WaitResult res = new WaitResult();
3394        // TODO: Switch to user app stacks here.
3395        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3396                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3397                res, null, options, userId, null);
3398        return res;
3399    }
3400
3401    @Override
3402    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3403            Intent intent, String resolvedType, IBinder resultTo,
3404            String resultWho, int requestCode, int startFlags, Configuration config,
3405            Bundle options, int userId) {
3406        enforceNotIsolatedCaller("startActivityWithConfig");
3407        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3408                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3409        // TODO: Switch to user app stacks here.
3410        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3411                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3412                null, null, null, config, options, userId, null);
3413        return ret;
3414    }
3415
3416    @Override
3417    public int startActivityIntentSender(IApplicationThread caller,
3418            IntentSender intent, Intent fillInIntent, String resolvedType,
3419            IBinder resultTo, String resultWho, int requestCode,
3420            int flagsMask, int flagsValues, Bundle options) {
3421        enforceNotIsolatedCaller("startActivityIntentSender");
3422        // Refuse possible leaked file descriptors
3423        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3424            throw new IllegalArgumentException("File descriptors passed in Intent");
3425        }
3426
3427        IIntentSender sender = intent.getTarget();
3428        if (!(sender instanceof PendingIntentRecord)) {
3429            throw new IllegalArgumentException("Bad PendingIntent object");
3430        }
3431
3432        PendingIntentRecord pir = (PendingIntentRecord)sender;
3433
3434        synchronized (this) {
3435            // If this is coming from the currently resumed activity, it is
3436            // effectively saying that app switches are allowed at this point.
3437            final ActivityStack stack = getFocusedStack();
3438            if (stack.mResumedActivity != null &&
3439                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3440                mAppSwitchesAllowedTime = 0;
3441            }
3442        }
3443        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3444                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3445        return ret;
3446    }
3447
3448    @Override
3449    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3450            Intent intent, String resolvedType, IVoiceInteractionSession session,
3451            IVoiceInteractor interactor, int startFlags, String profileFile,
3452            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3453        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3454                != PackageManager.PERMISSION_GRANTED) {
3455            String msg = "Permission Denial: startVoiceActivity() from pid="
3456                    + Binder.getCallingPid()
3457                    + ", uid=" + Binder.getCallingUid()
3458                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3459            Slog.w(TAG, msg);
3460            throw new SecurityException(msg);
3461        }
3462        if (session == null || interactor == null) {
3463            throw new NullPointerException("null session or interactor");
3464        }
3465        userId = handleIncomingUser(callingPid, callingUid, userId,
3466                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3467        // TODO: Switch to user app stacks here.
3468        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3469                resolvedType, session, interactor, null, null, 0, startFlags,
3470                profileFile, profileFd, null, null, options, userId, null);
3471    }
3472
3473    @Override
3474    public boolean startNextMatchingActivity(IBinder callingActivity,
3475            Intent intent, Bundle options) {
3476        // Refuse possible leaked file descriptors
3477        if (intent != null && intent.hasFileDescriptors() == true) {
3478            throw new IllegalArgumentException("File descriptors passed in Intent");
3479        }
3480
3481        synchronized (this) {
3482            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3483            if (r == null) {
3484                ActivityOptions.abort(options);
3485                return false;
3486            }
3487            if (r.app == null || r.app.thread == null) {
3488                // The caller is not running...  d'oh!
3489                ActivityOptions.abort(options);
3490                return false;
3491            }
3492            intent = new Intent(intent);
3493            // The caller is not allowed to change the data.
3494            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3495            // And we are resetting to find the next component...
3496            intent.setComponent(null);
3497
3498            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3499
3500            ActivityInfo aInfo = null;
3501            try {
3502                List<ResolveInfo> resolves =
3503                    AppGlobals.getPackageManager().queryIntentActivities(
3504                            intent, r.resolvedType,
3505                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3506                            UserHandle.getCallingUserId());
3507
3508                // Look for the original activity in the list...
3509                final int N = resolves != null ? resolves.size() : 0;
3510                for (int i=0; i<N; i++) {
3511                    ResolveInfo rInfo = resolves.get(i);
3512                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3513                            && rInfo.activityInfo.name.equals(r.info.name)) {
3514                        // We found the current one...  the next matching is
3515                        // after it.
3516                        i++;
3517                        if (i<N) {
3518                            aInfo = resolves.get(i).activityInfo;
3519                        }
3520                        if (debug) {
3521                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3522                                    + "/" + r.info.name);
3523                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3524                                    + "/" + aInfo.name);
3525                        }
3526                        break;
3527                    }
3528                }
3529            } catch (RemoteException e) {
3530            }
3531
3532            if (aInfo == null) {
3533                // Nobody who is next!
3534                ActivityOptions.abort(options);
3535                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3536                return false;
3537            }
3538
3539            intent.setComponent(new ComponentName(
3540                    aInfo.applicationInfo.packageName, aInfo.name));
3541            intent.setFlags(intent.getFlags()&~(
3542                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3543                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3544                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3545                    Intent.FLAG_ACTIVITY_NEW_TASK));
3546
3547            // Okay now we need to start the new activity, replacing the
3548            // currently running activity.  This is a little tricky because
3549            // we want to start the new one as if the current one is finished,
3550            // but not finish the current one first so that there is no flicker.
3551            // And thus...
3552            final boolean wasFinishing = r.finishing;
3553            r.finishing = true;
3554
3555            // Propagate reply information over to the new activity.
3556            final ActivityRecord resultTo = r.resultTo;
3557            final String resultWho = r.resultWho;
3558            final int requestCode = r.requestCode;
3559            r.resultTo = null;
3560            if (resultTo != null) {
3561                resultTo.removeResultsLocked(r, resultWho, requestCode);
3562            }
3563
3564            final long origId = Binder.clearCallingIdentity();
3565            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3566                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3567                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3568                    options, false, null, null);
3569            Binder.restoreCallingIdentity(origId);
3570
3571            r.finishing = wasFinishing;
3572            if (res != ActivityManager.START_SUCCESS) {
3573                return false;
3574            }
3575            return true;
3576        }
3577    }
3578
3579    @Override
3580    public final int startActivityFromRecents(int taskId, Bundle options) {
3581        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3582            String msg = "Permission Denial: startActivityFromRecents called without " +
3583                    START_TASKS_FROM_RECENTS;
3584            Slog.w(TAG, msg);
3585            throw new SecurityException(msg);
3586        }
3587        final int callingUid;
3588        final String callingPackage;
3589        final Intent intent;
3590        final int userId;
3591        synchronized (this) {
3592            final TaskRecord task = recentTaskForIdLocked(taskId);
3593            if (task == null) {
3594                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3595            }
3596            callingUid = task.mCallingUid;
3597            callingPackage = task.mCallingPackage;
3598            intent = task.intent;
3599            userId = task.userId;
3600        }
3601        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3602                options, userId, null);
3603    }
3604
3605    final int startActivityInPackage(int uid, String callingPackage,
3606            Intent intent, String resolvedType, IBinder resultTo,
3607            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3608                    IActivityContainer container) {
3609
3610        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3611                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3612
3613        // TODO: Switch to user app stacks here.
3614        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3615                null, null, resultTo, resultWho, requestCode, startFlags,
3616                null, null, null, null, options, userId, container);
3617        return ret;
3618    }
3619
3620    @Override
3621    public final int startActivities(IApplicationThread caller, String callingPackage,
3622            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3623            int userId) {
3624        enforceNotIsolatedCaller("startActivities");
3625        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3626                false, ALLOW_FULL_ONLY, "startActivity", null);
3627        // TODO: Switch to user app stacks here.
3628        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3629                resolvedTypes, resultTo, options, userId);
3630        return ret;
3631    }
3632
3633    final int startActivitiesInPackage(int uid, String callingPackage,
3634            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3635            Bundle options, int userId) {
3636
3637        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3638                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3639        // TODO: Switch to user app stacks here.
3640        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3641                resultTo, options, userId);
3642        return ret;
3643    }
3644
3645    //explicitly remove thd old information in mRecentTasks when removing existing user.
3646    private void removeRecentTasksForUser(int userId) {
3647        if(userId <= 0) {
3648            Slog.i(TAG, "Can't remove recent task on user " + userId);
3649            return;
3650        }
3651
3652        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3653            TaskRecord tr = mRecentTasks.get(i);
3654            if (tr.userId == userId) {
3655                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3656                        + " when finishing user" + userId);
3657                tr.disposeThumbnail();
3658                mRecentTasks.remove(i);
3659            }
3660        }
3661
3662        // Remove tasks from persistent storage.
3663        mTaskPersister.wakeup(null, true);
3664    }
3665
3666    final void addRecentTaskLocked(TaskRecord task) {
3667        int N = mRecentTasks.size();
3668        // Quick case: check if the top-most recent task is the same.
3669        if (N > 0 && mRecentTasks.get(0) == task) {
3670            return;
3671        }
3672        // Another quick case: never add voice sessions.
3673        if (task.voiceSession != null) {
3674            return;
3675        }
3676        // Remove any existing entries that are the same kind of task.
3677        final Intent intent = task.intent;
3678        final boolean document = intent != null && intent.isDocument();
3679        final ComponentName comp = intent.getComponent();
3680
3681        int maxRecents = task.maxRecents - 1;
3682        for (int i=0; i<N; i++) {
3683            final TaskRecord tr = mRecentTasks.get(i);
3684            if (task != tr) {
3685                if (task.userId != tr.userId) {
3686                    continue;
3687                }
3688                if (i > MAX_RECENT_BITMAPS) {
3689                    tr.freeLastThumbnail();
3690                }
3691                final Intent trIntent = tr.intent;
3692                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3693                    (intent == null || !intent.filterEquals(trIntent))) {
3694                    continue;
3695                }
3696                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3697                if (document && trIsDocument) {
3698                    // These are the same document activity (not necessarily the same doc).
3699                    if (maxRecents > 0) {
3700                        --maxRecents;
3701                        continue;
3702                    }
3703                    // Hit the maximum number of documents for this task. Fall through
3704                    // and remove this document from recents.
3705                } else if (document || trIsDocument) {
3706                    // Only one of these is a document. Not the droid we're looking for.
3707                    continue;
3708                }
3709            }
3710
3711            // Either task and tr are the same or, their affinities match or their intents match
3712            // and neither of them is a document, or they are documents using the same activity
3713            // and their maxRecents has been reached.
3714            tr.disposeThumbnail();
3715            mRecentTasks.remove(i);
3716            if (task != tr) {
3717                tr.closeRecentsChain();
3718            }
3719            i--;
3720            N--;
3721            if (task.intent == null) {
3722                // If the new recent task we are adding is not fully
3723                // specified, then replace it with the existing recent task.
3724                task = tr;
3725            }
3726            notifyTaskPersisterLocked(tr, false);
3727        }
3728        if (N >= MAX_RECENT_TASKS) {
3729            final TaskRecord tr = mRecentTasks.remove(N - 1);
3730            tr.disposeThumbnail();
3731            tr.closeRecentsChain();
3732        }
3733        mRecentTasks.add(0, task);
3734    }
3735
3736    @Override
3737    public void reportActivityFullyDrawn(IBinder token) {
3738        synchronized (this) {
3739            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3740            if (r == null) {
3741                return;
3742            }
3743            r.reportFullyDrawnLocked();
3744        }
3745    }
3746
3747    @Override
3748    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3749        synchronized (this) {
3750            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3751            if (r == null) {
3752                return;
3753            }
3754            final long origId = Binder.clearCallingIdentity();
3755            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3756            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3757                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3758            if (config != null) {
3759                r.frozenBeforeDestroy = true;
3760                if (!updateConfigurationLocked(config, r, false, false)) {
3761                    mStackSupervisor.resumeTopActivitiesLocked();
3762                }
3763            }
3764            Binder.restoreCallingIdentity(origId);
3765        }
3766    }
3767
3768    @Override
3769    public int getRequestedOrientation(IBinder token) {
3770        synchronized (this) {
3771            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3772            if (r == null) {
3773                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3774            }
3775            return mWindowManager.getAppOrientation(r.appToken);
3776        }
3777    }
3778
3779    /**
3780     * This is the internal entry point for handling Activity.finish().
3781     *
3782     * @param token The Binder token referencing the Activity we want to finish.
3783     * @param resultCode Result code, if any, from this Activity.
3784     * @param resultData Result data (Intent), if any, from this Activity.
3785     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3786     *            the root Activity in the task.
3787     *
3788     * @return Returns true if the activity successfully finished, or false if it is still running.
3789     */
3790    @Override
3791    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3792            boolean finishTask) {
3793        // Refuse possible leaked file descriptors
3794        if (resultData != null && resultData.hasFileDescriptors() == true) {
3795            throw new IllegalArgumentException("File descriptors passed in Intent");
3796        }
3797
3798        synchronized(this) {
3799            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3800            if (r == null) {
3801                return true;
3802            }
3803            // Keep track of the root activity of the task before we finish it
3804            TaskRecord tr = r.task;
3805            ActivityRecord rootR = tr.getRootActivity();
3806            // Do not allow task to finish in Lock Task mode.
3807            if (tr == mStackSupervisor.mLockTaskModeTask) {
3808                if (rootR == r) {
3809                    mStackSupervisor.showLockTaskToast();
3810                    return false;
3811                }
3812            }
3813            if (mController != null) {
3814                // Find the first activity that is not finishing.
3815                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3816                if (next != null) {
3817                    // ask watcher if this is allowed
3818                    boolean resumeOK = true;
3819                    try {
3820                        resumeOK = mController.activityResuming(next.packageName);
3821                    } catch (RemoteException e) {
3822                        mController = null;
3823                        Watchdog.getInstance().setActivityController(null);
3824                    }
3825
3826                    if (!resumeOK) {
3827                        return false;
3828                    }
3829                }
3830            }
3831            final long origId = Binder.clearCallingIdentity();
3832            try {
3833                boolean res;
3834                if (finishTask && r == rootR) {
3835                    // If requested, remove the task that is associated to this activity only if it
3836                    // was the root activity in the task.  The result code and data is ignored because
3837                    // we don't support returning them across task boundaries.
3838                    res = removeTaskByIdLocked(tr.taskId, 0);
3839                } else {
3840                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3841                            resultData, "app-request", true);
3842                }
3843                return res;
3844            } finally {
3845                Binder.restoreCallingIdentity(origId);
3846            }
3847        }
3848    }
3849
3850    @Override
3851    public final void finishHeavyWeightApp() {
3852        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3853                != PackageManager.PERMISSION_GRANTED) {
3854            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3855                    + Binder.getCallingPid()
3856                    + ", uid=" + Binder.getCallingUid()
3857                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3858            Slog.w(TAG, msg);
3859            throw new SecurityException(msg);
3860        }
3861
3862        synchronized(this) {
3863            if (mHeavyWeightProcess == null) {
3864                return;
3865            }
3866
3867            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3868                    mHeavyWeightProcess.activities);
3869            for (int i=0; i<activities.size(); i++) {
3870                ActivityRecord r = activities.get(i);
3871                if (!r.finishing) {
3872                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3873                            null, "finish-heavy", true);
3874                }
3875            }
3876
3877            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3878                    mHeavyWeightProcess.userId, 0));
3879            mHeavyWeightProcess = null;
3880        }
3881    }
3882
3883    @Override
3884    public void crashApplication(int uid, int initialPid, String packageName,
3885            String message) {
3886        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3887                != PackageManager.PERMISSION_GRANTED) {
3888            String msg = "Permission Denial: crashApplication() from pid="
3889                    + Binder.getCallingPid()
3890                    + ", uid=" + Binder.getCallingUid()
3891                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3892            Slog.w(TAG, msg);
3893            throw new SecurityException(msg);
3894        }
3895
3896        synchronized(this) {
3897            ProcessRecord proc = null;
3898
3899            // Figure out which process to kill.  We don't trust that initialPid
3900            // still has any relation to current pids, so must scan through the
3901            // list.
3902            synchronized (mPidsSelfLocked) {
3903                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3904                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3905                    if (p.uid != uid) {
3906                        continue;
3907                    }
3908                    if (p.pid == initialPid) {
3909                        proc = p;
3910                        break;
3911                    }
3912                    if (p.pkgList.containsKey(packageName)) {
3913                        proc = p;
3914                    }
3915                }
3916            }
3917
3918            if (proc == null) {
3919                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3920                        + " initialPid=" + initialPid
3921                        + " packageName=" + packageName);
3922                return;
3923            }
3924
3925            if (proc.thread != null) {
3926                if (proc.pid == Process.myPid()) {
3927                    Log.w(TAG, "crashApplication: trying to crash self!");
3928                    return;
3929                }
3930                long ident = Binder.clearCallingIdentity();
3931                try {
3932                    proc.thread.scheduleCrash(message);
3933                } catch (RemoteException e) {
3934                }
3935                Binder.restoreCallingIdentity(ident);
3936            }
3937        }
3938    }
3939
3940    @Override
3941    public final void finishSubActivity(IBinder token, String resultWho,
3942            int requestCode) {
3943        synchronized(this) {
3944            final long origId = Binder.clearCallingIdentity();
3945            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3946            if (r != null) {
3947                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3948            }
3949            Binder.restoreCallingIdentity(origId);
3950        }
3951    }
3952
3953    @Override
3954    public boolean finishActivityAffinity(IBinder token) {
3955        synchronized(this) {
3956            final long origId = Binder.clearCallingIdentity();
3957            try {
3958                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3959
3960                ActivityRecord rootR = r.task.getRootActivity();
3961                // Do not allow task to finish in Lock Task mode.
3962                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3963                    if (rootR == r) {
3964                        mStackSupervisor.showLockTaskToast();
3965                        return false;
3966                    }
3967                }
3968                boolean res = false;
3969                if (r != null) {
3970                    res = r.task.stack.finishActivityAffinityLocked(r);
3971                }
3972                return res;
3973            } finally {
3974                Binder.restoreCallingIdentity(origId);
3975            }
3976        }
3977    }
3978
3979    @Override
3980    public void finishVoiceTask(IVoiceInteractionSession session) {
3981        synchronized(this) {
3982            final long origId = Binder.clearCallingIdentity();
3983            try {
3984                mStackSupervisor.finishVoiceTask(session);
3985            } finally {
3986                Binder.restoreCallingIdentity(origId);
3987            }
3988        }
3989
3990    }
3991
3992    @Override
3993    public boolean willActivityBeVisible(IBinder token) {
3994        synchronized(this) {
3995            ActivityStack stack = ActivityRecord.getStackLocked(token);
3996            if (stack != null) {
3997                return stack.willActivityBeVisibleLocked(token);
3998            }
3999            return false;
4000        }
4001    }
4002
4003    @Override
4004    public void overridePendingTransition(IBinder token, String packageName,
4005            int enterAnim, int exitAnim) {
4006        synchronized(this) {
4007            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4008            if (self == null) {
4009                return;
4010            }
4011
4012            final long origId = Binder.clearCallingIdentity();
4013
4014            if (self.state == ActivityState.RESUMED
4015                    || self.state == ActivityState.PAUSING) {
4016                mWindowManager.overridePendingAppTransition(packageName,
4017                        enterAnim, exitAnim, null);
4018            }
4019
4020            Binder.restoreCallingIdentity(origId);
4021        }
4022    }
4023
4024    /**
4025     * Main function for removing an existing process from the activity manager
4026     * as a result of that process going away.  Clears out all connections
4027     * to the process.
4028     */
4029    private final void handleAppDiedLocked(ProcessRecord app,
4030            boolean restarting, boolean allowRestart) {
4031        int pid = app.pid;
4032        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4033        if (!restarting) {
4034            removeLruProcessLocked(app);
4035            if (pid > 0) {
4036                ProcessList.remove(pid);
4037            }
4038        }
4039
4040        if (mProfileProc == app) {
4041            clearProfilerLocked();
4042        }
4043
4044        // Remove this application's activities from active lists.
4045        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4046
4047        app.activities.clear();
4048
4049        if (app.instrumentationClass != null) {
4050            Slog.w(TAG, "Crash of app " + app.processName
4051                  + " running instrumentation " + app.instrumentationClass);
4052            Bundle info = new Bundle();
4053            info.putString("shortMsg", "Process crashed.");
4054            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4055        }
4056
4057        if (!restarting) {
4058            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4059                // If there was nothing to resume, and we are not already
4060                // restarting this process, but there is a visible activity that
4061                // is hosted by the process...  then make sure all visible
4062                // activities are running, taking care of restarting this
4063                // process.
4064                if (hasVisibleActivities) {
4065                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4066                }
4067            }
4068        }
4069    }
4070
4071    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4072        IBinder threadBinder = thread.asBinder();
4073        // Find the application record.
4074        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4075            ProcessRecord rec = mLruProcesses.get(i);
4076            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4077                return i;
4078            }
4079        }
4080        return -1;
4081    }
4082
4083    final ProcessRecord getRecordForAppLocked(
4084            IApplicationThread thread) {
4085        if (thread == null) {
4086            return null;
4087        }
4088
4089        int appIndex = getLRURecordIndexForAppLocked(thread);
4090        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4091    }
4092
4093    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4094        // If there are no longer any background processes running,
4095        // and the app that died was not running instrumentation,
4096        // then tell everyone we are now low on memory.
4097        boolean haveBg = false;
4098        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4099            ProcessRecord rec = mLruProcesses.get(i);
4100            if (rec.thread != null
4101                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4102                haveBg = true;
4103                break;
4104            }
4105        }
4106
4107        if (!haveBg) {
4108            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4109            if (doReport) {
4110                long now = SystemClock.uptimeMillis();
4111                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4112                    doReport = false;
4113                } else {
4114                    mLastMemUsageReportTime = now;
4115                }
4116            }
4117            final ArrayList<ProcessMemInfo> memInfos
4118                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4119            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4120            long now = SystemClock.uptimeMillis();
4121            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4122                ProcessRecord rec = mLruProcesses.get(i);
4123                if (rec == dyingProc || rec.thread == null) {
4124                    continue;
4125                }
4126                if (doReport) {
4127                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4128                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4129                }
4130                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4131                    // The low memory report is overriding any current
4132                    // state for a GC request.  Make sure to do
4133                    // heavy/important/visible/foreground processes first.
4134                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4135                        rec.lastRequestedGc = 0;
4136                    } else {
4137                        rec.lastRequestedGc = rec.lastLowMemory;
4138                    }
4139                    rec.reportLowMemory = true;
4140                    rec.lastLowMemory = now;
4141                    mProcessesToGc.remove(rec);
4142                    addProcessToGcListLocked(rec);
4143                }
4144            }
4145            if (doReport) {
4146                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4147                mHandler.sendMessage(msg);
4148            }
4149            scheduleAppGcsLocked();
4150        }
4151    }
4152
4153    final void appDiedLocked(ProcessRecord app, int pid,
4154            IApplicationThread thread) {
4155
4156        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4157        synchronized (stats) {
4158            stats.noteProcessDiedLocked(app.info.uid, pid);
4159        }
4160
4161        Process.killProcessGroup(app.info.uid, pid);
4162
4163        // Clean up already done if the process has been re-started.
4164        if (app.pid == pid && app.thread != null &&
4165                app.thread.asBinder() == thread.asBinder()) {
4166            boolean doLowMem = app.instrumentationClass == null;
4167            boolean doOomAdj = doLowMem;
4168            if (!app.killedByAm) {
4169                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4170                        + ") has died.");
4171                mAllowLowerMemLevel = true;
4172            } else {
4173                // Note that we always want to do oom adj to update our state with the
4174                // new number of procs.
4175                mAllowLowerMemLevel = false;
4176                doLowMem = false;
4177            }
4178            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4179            if (DEBUG_CLEANUP) Slog.v(
4180                TAG, "Dying app: " + app + ", pid: " + pid
4181                + ", thread: " + thread.asBinder());
4182            handleAppDiedLocked(app, false, true);
4183
4184            if (doOomAdj) {
4185                updateOomAdjLocked();
4186            }
4187            if (doLowMem) {
4188                doLowMemReportIfNeededLocked(app);
4189            }
4190        } else if (app.pid != pid) {
4191            // A new process has already been started.
4192            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4193                    + ") has died and restarted (pid " + app.pid + ").");
4194            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4195        } else if (DEBUG_PROCESSES) {
4196            Slog.d(TAG, "Received spurious death notification for thread "
4197                    + thread.asBinder());
4198        }
4199    }
4200
4201    /**
4202     * If a stack trace dump file is configured, dump process stack traces.
4203     * @param clearTraces causes the dump file to be erased prior to the new
4204     *    traces being written, if true; when false, the new traces will be
4205     *    appended to any existing file content.
4206     * @param firstPids of dalvik VM processes to dump stack traces for first
4207     * @param lastPids of dalvik VM processes to dump stack traces for last
4208     * @param nativeProcs optional list of native process names to dump stack crawls
4209     * @return file containing stack traces, or null if no dump file is configured
4210     */
4211    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4212            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4213        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4214        if (tracesPath == null || tracesPath.length() == 0) {
4215            return null;
4216        }
4217
4218        File tracesFile = new File(tracesPath);
4219        try {
4220            File tracesDir = tracesFile.getParentFile();
4221            if (!tracesDir.exists()) {
4222                tracesFile.mkdirs();
4223                if (!SELinux.restorecon(tracesDir)) {
4224                    return null;
4225                }
4226            }
4227            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4228
4229            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4230            tracesFile.createNewFile();
4231            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4232        } catch (IOException e) {
4233            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4234            return null;
4235        }
4236
4237        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4238        return tracesFile;
4239    }
4240
4241    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4242            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4243        // Use a FileObserver to detect when traces finish writing.
4244        // The order of traces is considered important to maintain for legibility.
4245        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4246            @Override
4247            public synchronized void onEvent(int event, String path) { notify(); }
4248        };
4249
4250        try {
4251            observer.startWatching();
4252
4253            // First collect all of the stacks of the most important pids.
4254            if (firstPids != null) {
4255                try {
4256                    int num = firstPids.size();
4257                    for (int i = 0; i < num; i++) {
4258                        synchronized (observer) {
4259                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4260                            observer.wait(200);  // Wait for write-close, give up after 200msec
4261                        }
4262                    }
4263                } catch (InterruptedException e) {
4264                    Log.wtf(TAG, e);
4265                }
4266            }
4267
4268            // Next collect the stacks of the native pids
4269            if (nativeProcs != null) {
4270                int[] pids = Process.getPidsForCommands(nativeProcs);
4271                if (pids != null) {
4272                    for (int pid : pids) {
4273                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4274                    }
4275                }
4276            }
4277
4278            // Lastly, measure CPU usage.
4279            if (processCpuTracker != null) {
4280                processCpuTracker.init();
4281                System.gc();
4282                processCpuTracker.update();
4283                try {
4284                    synchronized (processCpuTracker) {
4285                        processCpuTracker.wait(500); // measure over 1/2 second.
4286                    }
4287                } catch (InterruptedException e) {
4288                }
4289                processCpuTracker.update();
4290
4291                // We'll take the stack crawls of just the top apps using CPU.
4292                final int N = processCpuTracker.countWorkingStats();
4293                int numProcs = 0;
4294                for (int i=0; i<N && numProcs<5; i++) {
4295                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4296                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4297                        numProcs++;
4298                        try {
4299                            synchronized (observer) {
4300                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4301                                observer.wait(200);  // Wait for write-close, give up after 200msec
4302                            }
4303                        } catch (InterruptedException e) {
4304                            Log.wtf(TAG, e);
4305                        }
4306
4307                    }
4308                }
4309            }
4310        } finally {
4311            observer.stopWatching();
4312        }
4313    }
4314
4315    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4316        if (true || IS_USER_BUILD) {
4317            return;
4318        }
4319        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4320        if (tracesPath == null || tracesPath.length() == 0) {
4321            return;
4322        }
4323
4324        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4325        StrictMode.allowThreadDiskWrites();
4326        try {
4327            final File tracesFile = new File(tracesPath);
4328            final File tracesDir = tracesFile.getParentFile();
4329            final File tracesTmp = new File(tracesDir, "__tmp__");
4330            try {
4331                if (!tracesDir.exists()) {
4332                    tracesFile.mkdirs();
4333                    if (!SELinux.restorecon(tracesDir.getPath())) {
4334                        return;
4335                    }
4336                }
4337                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4338
4339                if (tracesFile.exists()) {
4340                    tracesTmp.delete();
4341                    tracesFile.renameTo(tracesTmp);
4342                }
4343                StringBuilder sb = new StringBuilder();
4344                Time tobj = new Time();
4345                tobj.set(System.currentTimeMillis());
4346                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4347                sb.append(": ");
4348                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4349                sb.append(" since ");
4350                sb.append(msg);
4351                FileOutputStream fos = new FileOutputStream(tracesFile);
4352                fos.write(sb.toString().getBytes());
4353                if (app == null) {
4354                    fos.write("\n*** No application process!".getBytes());
4355                }
4356                fos.close();
4357                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4358            } catch (IOException e) {
4359                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4360                return;
4361            }
4362
4363            if (app != null) {
4364                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4365                firstPids.add(app.pid);
4366                dumpStackTraces(tracesPath, firstPids, null, null, null);
4367            }
4368
4369            File lastTracesFile = null;
4370            File curTracesFile = null;
4371            for (int i=9; i>=0; i--) {
4372                String name = String.format(Locale.US, "slow%02d.txt", i);
4373                curTracesFile = new File(tracesDir, name);
4374                if (curTracesFile.exists()) {
4375                    if (lastTracesFile != null) {
4376                        curTracesFile.renameTo(lastTracesFile);
4377                    } else {
4378                        curTracesFile.delete();
4379                    }
4380                }
4381                lastTracesFile = curTracesFile;
4382            }
4383            tracesFile.renameTo(curTracesFile);
4384            if (tracesTmp.exists()) {
4385                tracesTmp.renameTo(tracesFile);
4386            }
4387        } finally {
4388            StrictMode.setThreadPolicy(oldPolicy);
4389        }
4390    }
4391
4392    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4393            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4394        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4395        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4396
4397        if (mController != null) {
4398            try {
4399                // 0 == continue, -1 = kill process immediately
4400                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4401                if (res < 0 && app.pid != MY_PID) {
4402                    Process.killProcess(app.pid);
4403                    Process.killProcessGroup(app.info.uid, app.pid);
4404                }
4405            } catch (RemoteException e) {
4406                mController = null;
4407                Watchdog.getInstance().setActivityController(null);
4408            }
4409        }
4410
4411        long anrTime = SystemClock.uptimeMillis();
4412        if (MONITOR_CPU_USAGE) {
4413            updateCpuStatsNow();
4414        }
4415
4416        synchronized (this) {
4417            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4418            if (mShuttingDown) {
4419                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4420                return;
4421            } else if (app.notResponding) {
4422                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4423                return;
4424            } else if (app.crashing) {
4425                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4426                return;
4427            }
4428
4429            // In case we come through here for the same app before completing
4430            // this one, mark as anring now so we will bail out.
4431            app.notResponding = true;
4432
4433            // Log the ANR to the event log.
4434            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4435                    app.processName, app.info.flags, annotation);
4436
4437            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4438            firstPids.add(app.pid);
4439
4440            int parentPid = app.pid;
4441            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4442            if (parentPid != app.pid) firstPids.add(parentPid);
4443
4444            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4445
4446            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4447                ProcessRecord r = mLruProcesses.get(i);
4448                if (r != null && r.thread != null) {
4449                    int pid = r.pid;
4450                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4451                        if (r.persistent) {
4452                            firstPids.add(pid);
4453                        } else {
4454                            lastPids.put(pid, Boolean.TRUE);
4455                        }
4456                    }
4457                }
4458            }
4459        }
4460
4461        // Log the ANR to the main log.
4462        StringBuilder info = new StringBuilder();
4463        info.setLength(0);
4464        info.append("ANR in ").append(app.processName);
4465        if (activity != null && activity.shortComponentName != null) {
4466            info.append(" (").append(activity.shortComponentName).append(")");
4467        }
4468        info.append("\n");
4469        info.append("PID: ").append(app.pid).append("\n");
4470        if (annotation != null) {
4471            info.append("Reason: ").append(annotation).append("\n");
4472        }
4473        if (parent != null && parent != activity) {
4474            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4475        }
4476
4477        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4478
4479        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4480                NATIVE_STACKS_OF_INTEREST);
4481
4482        String cpuInfo = null;
4483        if (MONITOR_CPU_USAGE) {
4484            updateCpuStatsNow();
4485            synchronized (mProcessCpuThread) {
4486                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4487            }
4488            info.append(processCpuTracker.printCurrentLoad());
4489            info.append(cpuInfo);
4490        }
4491
4492        info.append(processCpuTracker.printCurrentState(anrTime));
4493
4494        Slog.e(TAG, info.toString());
4495        if (tracesFile == null) {
4496            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4497            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4498        }
4499
4500        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4501                cpuInfo, tracesFile, null);
4502
4503        if (mController != null) {
4504            try {
4505                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4506                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4507                if (res != 0) {
4508                    if (res < 0 && app.pid != MY_PID) {
4509                        Process.killProcess(app.pid);
4510                        Process.killProcessGroup(app.info.uid, app.pid);
4511                    } else {
4512                        synchronized (this) {
4513                            mServices.scheduleServiceTimeoutLocked(app);
4514                        }
4515                    }
4516                    return;
4517                }
4518            } catch (RemoteException e) {
4519                mController = null;
4520                Watchdog.getInstance().setActivityController(null);
4521            }
4522        }
4523
4524        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4525        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4526                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4527
4528        synchronized (this) {
4529            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4530                killUnneededProcessLocked(app, "background ANR");
4531                return;
4532            }
4533
4534            // Set the app's notResponding state, and look up the errorReportReceiver
4535            makeAppNotRespondingLocked(app,
4536                    activity != null ? activity.shortComponentName : null,
4537                    annotation != null ? "ANR " + annotation : "ANR",
4538                    info.toString());
4539
4540            // Bring up the infamous App Not Responding dialog
4541            Message msg = Message.obtain();
4542            HashMap<String, Object> map = new HashMap<String, Object>();
4543            msg.what = SHOW_NOT_RESPONDING_MSG;
4544            msg.obj = map;
4545            msg.arg1 = aboveSystem ? 1 : 0;
4546            map.put("app", app);
4547            if (activity != null) {
4548                map.put("activity", activity);
4549            }
4550
4551            mHandler.sendMessage(msg);
4552        }
4553    }
4554
4555    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4556        if (!mLaunchWarningShown) {
4557            mLaunchWarningShown = true;
4558            mHandler.post(new Runnable() {
4559                @Override
4560                public void run() {
4561                    synchronized (ActivityManagerService.this) {
4562                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4563                        d.show();
4564                        mHandler.postDelayed(new Runnable() {
4565                            @Override
4566                            public void run() {
4567                                synchronized (ActivityManagerService.this) {
4568                                    d.dismiss();
4569                                    mLaunchWarningShown = false;
4570                                }
4571                            }
4572                        }, 4000);
4573                    }
4574                }
4575            });
4576        }
4577    }
4578
4579    @Override
4580    public boolean clearApplicationUserData(final String packageName,
4581            final IPackageDataObserver observer, int userId) {
4582        enforceNotIsolatedCaller("clearApplicationUserData");
4583        int uid = Binder.getCallingUid();
4584        int pid = Binder.getCallingPid();
4585        userId = handleIncomingUser(pid, uid,
4586                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4587        long callingId = Binder.clearCallingIdentity();
4588        try {
4589            IPackageManager pm = AppGlobals.getPackageManager();
4590            int pkgUid = -1;
4591            synchronized(this) {
4592                try {
4593                    pkgUid = pm.getPackageUid(packageName, userId);
4594                } catch (RemoteException e) {
4595                }
4596                if (pkgUid == -1) {
4597                    Slog.w(TAG, "Invalid packageName: " + packageName);
4598                    if (observer != null) {
4599                        try {
4600                            observer.onRemoveCompleted(packageName, false);
4601                        } catch (RemoteException e) {
4602                            Slog.i(TAG, "Observer no longer exists.");
4603                        }
4604                    }
4605                    return false;
4606                }
4607                if (uid == pkgUid || checkComponentPermission(
4608                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4609                        pid, uid, -1, true)
4610                        == PackageManager.PERMISSION_GRANTED) {
4611                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4612                } else {
4613                    throw new SecurityException("PID " + pid + " does not have permission "
4614                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4615                                    + " of package " + packageName);
4616                }
4617            }
4618
4619            try {
4620                // Clear application user data
4621                pm.clearApplicationUserData(packageName, observer, userId);
4622
4623                // Remove all permissions granted from/to this package
4624                removeUriPermissionsForPackageLocked(packageName, userId, true);
4625
4626                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4627                        Uri.fromParts("package", packageName, null));
4628                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4629                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4630                        null, null, 0, null, null, null, false, false, userId);
4631            } catch (RemoteException e) {
4632            }
4633        } finally {
4634            Binder.restoreCallingIdentity(callingId);
4635        }
4636        return true;
4637    }
4638
4639    @Override
4640    public void killBackgroundProcesses(final String packageName, int userId) {
4641        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4642                != PackageManager.PERMISSION_GRANTED &&
4643                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4644                        != PackageManager.PERMISSION_GRANTED) {
4645            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4646                    + Binder.getCallingPid()
4647                    + ", uid=" + Binder.getCallingUid()
4648                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4649            Slog.w(TAG, msg);
4650            throw new SecurityException(msg);
4651        }
4652
4653        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4654                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4655        long callingId = Binder.clearCallingIdentity();
4656        try {
4657            IPackageManager pm = AppGlobals.getPackageManager();
4658            synchronized(this) {
4659                int appId = -1;
4660                try {
4661                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4662                } catch (RemoteException e) {
4663                }
4664                if (appId == -1) {
4665                    Slog.w(TAG, "Invalid packageName: " + packageName);
4666                    return;
4667                }
4668                killPackageProcessesLocked(packageName, appId, userId,
4669                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4670            }
4671        } finally {
4672            Binder.restoreCallingIdentity(callingId);
4673        }
4674    }
4675
4676    @Override
4677    public void killAllBackgroundProcesses() {
4678        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4679                != PackageManager.PERMISSION_GRANTED) {
4680            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4681                    + Binder.getCallingPid()
4682                    + ", uid=" + Binder.getCallingUid()
4683                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4684            Slog.w(TAG, msg);
4685            throw new SecurityException(msg);
4686        }
4687
4688        long callingId = Binder.clearCallingIdentity();
4689        try {
4690            synchronized(this) {
4691                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4692                final int NP = mProcessNames.getMap().size();
4693                for (int ip=0; ip<NP; ip++) {
4694                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4695                    final int NA = apps.size();
4696                    for (int ia=0; ia<NA; ia++) {
4697                        ProcessRecord app = apps.valueAt(ia);
4698                        if (app.persistent) {
4699                            // we don't kill persistent processes
4700                            continue;
4701                        }
4702                        if (app.removed) {
4703                            procs.add(app);
4704                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4705                            app.removed = true;
4706                            procs.add(app);
4707                        }
4708                    }
4709                }
4710
4711                int N = procs.size();
4712                for (int i=0; i<N; i++) {
4713                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4714                }
4715                mAllowLowerMemLevel = true;
4716                updateOomAdjLocked();
4717                doLowMemReportIfNeededLocked(null);
4718            }
4719        } finally {
4720            Binder.restoreCallingIdentity(callingId);
4721        }
4722    }
4723
4724    @Override
4725    public void forceStopPackage(final String packageName, int userId) {
4726        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4727                != PackageManager.PERMISSION_GRANTED) {
4728            String msg = "Permission Denial: forceStopPackage() from pid="
4729                    + Binder.getCallingPid()
4730                    + ", uid=" + Binder.getCallingUid()
4731                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4732            Slog.w(TAG, msg);
4733            throw new SecurityException(msg);
4734        }
4735        final int callingPid = Binder.getCallingPid();
4736        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4737                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4738        long callingId = Binder.clearCallingIdentity();
4739        try {
4740            IPackageManager pm = AppGlobals.getPackageManager();
4741            synchronized(this) {
4742                int[] users = userId == UserHandle.USER_ALL
4743                        ? getUsersLocked() : new int[] { userId };
4744                for (int user : users) {
4745                    int pkgUid = -1;
4746                    try {
4747                        pkgUid = pm.getPackageUid(packageName, user);
4748                    } catch (RemoteException e) {
4749                    }
4750                    if (pkgUid == -1) {
4751                        Slog.w(TAG, "Invalid packageName: " + packageName);
4752                        continue;
4753                    }
4754                    try {
4755                        pm.setPackageStoppedState(packageName, true, user);
4756                    } catch (RemoteException e) {
4757                    } catch (IllegalArgumentException e) {
4758                        Slog.w(TAG, "Failed trying to unstop package "
4759                                + packageName + ": " + e);
4760                    }
4761                    if (isUserRunningLocked(user, false)) {
4762                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4763                    }
4764                }
4765            }
4766        } finally {
4767            Binder.restoreCallingIdentity(callingId);
4768        }
4769    }
4770
4771    @Override
4772    public void addPackageDependency(String packageName) {
4773        synchronized (this) {
4774            int callingPid = Binder.getCallingPid();
4775            if (callingPid == Process.myPid()) {
4776                //  Yeah, um, no.
4777                Slog.w(TAG, "Can't addPackageDependency on system process");
4778                return;
4779            }
4780            ProcessRecord proc;
4781            synchronized (mPidsSelfLocked) {
4782                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4783            }
4784            if (proc != null) {
4785                if (proc.pkgDeps == null) {
4786                    proc.pkgDeps = new ArraySet<String>(1);
4787                }
4788                proc.pkgDeps.add(packageName);
4789            }
4790        }
4791    }
4792
4793    /*
4794     * The pkg name and app id have to be specified.
4795     */
4796    @Override
4797    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4798        if (pkg == null) {
4799            return;
4800        }
4801        // Make sure the uid is valid.
4802        if (appid < 0) {
4803            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4804            return;
4805        }
4806        int callerUid = Binder.getCallingUid();
4807        // Only the system server can kill an application
4808        if (callerUid == Process.SYSTEM_UID) {
4809            // Post an aysnc message to kill the application
4810            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4811            msg.arg1 = appid;
4812            msg.arg2 = 0;
4813            Bundle bundle = new Bundle();
4814            bundle.putString("pkg", pkg);
4815            bundle.putString("reason", reason);
4816            msg.obj = bundle;
4817            mHandler.sendMessage(msg);
4818        } else {
4819            throw new SecurityException(callerUid + " cannot kill pkg: " +
4820                    pkg);
4821        }
4822    }
4823
4824    @Override
4825    public void closeSystemDialogs(String reason) {
4826        enforceNotIsolatedCaller("closeSystemDialogs");
4827
4828        final int pid = Binder.getCallingPid();
4829        final int uid = Binder.getCallingUid();
4830        final long origId = Binder.clearCallingIdentity();
4831        try {
4832            synchronized (this) {
4833                // Only allow this from foreground processes, so that background
4834                // applications can't abuse it to prevent system UI from being shown.
4835                if (uid >= Process.FIRST_APPLICATION_UID) {
4836                    ProcessRecord proc;
4837                    synchronized (mPidsSelfLocked) {
4838                        proc = mPidsSelfLocked.get(pid);
4839                    }
4840                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4841                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4842                                + " from background process " + proc);
4843                        return;
4844                    }
4845                }
4846                closeSystemDialogsLocked(reason);
4847            }
4848        } finally {
4849            Binder.restoreCallingIdentity(origId);
4850        }
4851    }
4852
4853    void closeSystemDialogsLocked(String reason) {
4854        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4855        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4856                | Intent.FLAG_RECEIVER_FOREGROUND);
4857        if (reason != null) {
4858            intent.putExtra("reason", reason);
4859        }
4860        mWindowManager.closeSystemDialogs(reason);
4861
4862        mStackSupervisor.closeSystemDialogsLocked();
4863
4864        broadcastIntentLocked(null, null, intent, null,
4865                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4866                Process.SYSTEM_UID, UserHandle.USER_ALL);
4867    }
4868
4869    @Override
4870    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4871        enforceNotIsolatedCaller("getProcessMemoryInfo");
4872        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4873        for (int i=pids.length-1; i>=0; i--) {
4874            ProcessRecord proc;
4875            int oomAdj;
4876            synchronized (this) {
4877                synchronized (mPidsSelfLocked) {
4878                    proc = mPidsSelfLocked.get(pids[i]);
4879                    oomAdj = proc != null ? proc.setAdj : 0;
4880                }
4881            }
4882            infos[i] = new Debug.MemoryInfo();
4883            Debug.getMemoryInfo(pids[i], infos[i]);
4884            if (proc != null) {
4885                synchronized (this) {
4886                    if (proc.thread != null && proc.setAdj == oomAdj) {
4887                        // Record this for posterity if the process has been stable.
4888                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4889                                infos[i].getTotalUss(), false, proc.pkgList);
4890                    }
4891                }
4892            }
4893        }
4894        return infos;
4895    }
4896
4897    @Override
4898    public long[] getProcessPss(int[] pids) {
4899        enforceNotIsolatedCaller("getProcessPss");
4900        long[] pss = new long[pids.length];
4901        for (int i=pids.length-1; i>=0; i--) {
4902            ProcessRecord proc;
4903            int oomAdj;
4904            synchronized (this) {
4905                synchronized (mPidsSelfLocked) {
4906                    proc = mPidsSelfLocked.get(pids[i]);
4907                    oomAdj = proc != null ? proc.setAdj : 0;
4908                }
4909            }
4910            long[] tmpUss = new long[1];
4911            pss[i] = Debug.getPss(pids[i], tmpUss);
4912            if (proc != null) {
4913                synchronized (this) {
4914                    if (proc.thread != null && proc.setAdj == oomAdj) {
4915                        // Record this for posterity if the process has been stable.
4916                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4917                    }
4918                }
4919            }
4920        }
4921        return pss;
4922    }
4923
4924    @Override
4925    public void killApplicationProcess(String processName, int uid) {
4926        if (processName == null) {
4927            return;
4928        }
4929
4930        int callerUid = Binder.getCallingUid();
4931        // Only the system server can kill an application
4932        if (callerUid == Process.SYSTEM_UID) {
4933            synchronized (this) {
4934                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4935                if (app != null && app.thread != null) {
4936                    try {
4937                        app.thread.scheduleSuicide();
4938                    } catch (RemoteException e) {
4939                        // If the other end already died, then our work here is done.
4940                    }
4941                } else {
4942                    Slog.w(TAG, "Process/uid not found attempting kill of "
4943                            + processName + " / " + uid);
4944                }
4945            }
4946        } else {
4947            throw new SecurityException(callerUid + " cannot kill app process: " +
4948                    processName);
4949        }
4950    }
4951
4952    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4953        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4954                false, true, false, false, UserHandle.getUserId(uid), reason);
4955        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4956                Uri.fromParts("package", packageName, null));
4957        if (!mProcessesReady) {
4958            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4959                    | Intent.FLAG_RECEIVER_FOREGROUND);
4960        }
4961        intent.putExtra(Intent.EXTRA_UID, uid);
4962        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4963        broadcastIntentLocked(null, null, intent,
4964                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4965                false, false,
4966                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4967    }
4968
4969    private void forceStopUserLocked(int userId, String reason) {
4970        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4971        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4972        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4973                | Intent.FLAG_RECEIVER_FOREGROUND);
4974        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4975        broadcastIntentLocked(null, null, intent,
4976                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4977                false, false,
4978                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4979    }
4980
4981    private final boolean killPackageProcessesLocked(String packageName, int appId,
4982            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4983            boolean doit, boolean evenPersistent, String reason) {
4984        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4985
4986        // Remove all processes this package may have touched: all with the
4987        // same UID (except for the system or root user), and all whose name
4988        // matches the package name.
4989        final int NP = mProcessNames.getMap().size();
4990        for (int ip=0; ip<NP; ip++) {
4991            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4992            final int NA = apps.size();
4993            for (int ia=0; ia<NA; ia++) {
4994                ProcessRecord app = apps.valueAt(ia);
4995                if (app.persistent && !evenPersistent) {
4996                    // we don't kill persistent processes
4997                    continue;
4998                }
4999                if (app.removed) {
5000                    if (doit) {
5001                        procs.add(app);
5002                    }
5003                    continue;
5004                }
5005
5006                // Skip process if it doesn't meet our oom adj requirement.
5007                if (app.setAdj < minOomAdj) {
5008                    continue;
5009                }
5010
5011                // If no package is specified, we call all processes under the
5012                // give user id.
5013                if (packageName == null) {
5014                    if (app.userId != userId) {
5015                        continue;
5016                    }
5017                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5018                        continue;
5019                    }
5020                // Package has been specified, we want to hit all processes
5021                // that match it.  We need to qualify this by the processes
5022                // that are running under the specified app and user ID.
5023                } else {
5024                    final boolean isDep = app.pkgDeps != null
5025                            && app.pkgDeps.contains(packageName);
5026                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5027                        continue;
5028                    }
5029                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5030                        continue;
5031                    }
5032                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5033                        continue;
5034                    }
5035                }
5036
5037                // Process has passed all conditions, kill it!
5038                if (!doit) {
5039                    return true;
5040                }
5041                app.removed = true;
5042                procs.add(app);
5043            }
5044        }
5045
5046        int N = procs.size();
5047        for (int i=0; i<N; i++) {
5048            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5049        }
5050        updateOomAdjLocked();
5051        return N > 0;
5052    }
5053
5054    private final boolean forceStopPackageLocked(String name, int appId,
5055            boolean callerWillRestart, boolean purgeCache, boolean doit,
5056            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5057        int i;
5058        int N;
5059
5060        if (userId == UserHandle.USER_ALL && name == null) {
5061            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5062        }
5063
5064        if (appId < 0 && name != null) {
5065            try {
5066                appId = UserHandle.getAppId(
5067                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5068            } catch (RemoteException e) {
5069            }
5070        }
5071
5072        if (doit) {
5073            if (name != null) {
5074                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5075                        + " user=" + userId + ": " + reason);
5076            } else {
5077                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5078            }
5079
5080            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5081            for (int ip=pmap.size()-1; ip>=0; ip--) {
5082                SparseArray<Long> ba = pmap.valueAt(ip);
5083                for (i=ba.size()-1; i>=0; i--) {
5084                    boolean remove = false;
5085                    final int entUid = ba.keyAt(i);
5086                    if (name != null) {
5087                        if (userId == UserHandle.USER_ALL) {
5088                            if (UserHandle.getAppId(entUid) == appId) {
5089                                remove = true;
5090                            }
5091                        } else {
5092                            if (entUid == UserHandle.getUid(userId, appId)) {
5093                                remove = true;
5094                            }
5095                        }
5096                    } else if (UserHandle.getUserId(entUid) == userId) {
5097                        remove = true;
5098                    }
5099                    if (remove) {
5100                        ba.removeAt(i);
5101                    }
5102                }
5103                if (ba.size() == 0) {
5104                    pmap.removeAt(ip);
5105                }
5106            }
5107        }
5108
5109        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5110                -100, callerWillRestart, true, doit, evenPersistent,
5111                name == null ? ("stop user " + userId) : ("stop " + name));
5112
5113        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5114            if (!doit) {
5115                return true;
5116            }
5117            didSomething = true;
5118        }
5119
5120        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5121            if (!doit) {
5122                return true;
5123            }
5124            didSomething = true;
5125        }
5126
5127        if (name == null) {
5128            // Remove all sticky broadcasts from this user.
5129            mStickyBroadcasts.remove(userId);
5130        }
5131
5132        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5133        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5134                userId, providers)) {
5135            if (!doit) {
5136                return true;
5137            }
5138            didSomething = true;
5139        }
5140        N = providers.size();
5141        for (i=0; i<N; i++) {
5142            removeDyingProviderLocked(null, providers.get(i), true);
5143        }
5144
5145        // Remove transient permissions granted from/to this package/user
5146        removeUriPermissionsForPackageLocked(name, userId, false);
5147
5148        if (name == null || uninstalling) {
5149            // Remove pending intents.  For now we only do this when force
5150            // stopping users, because we have some problems when doing this
5151            // for packages -- app widgets are not currently cleaned up for
5152            // such packages, so they can be left with bad pending intents.
5153            if (mIntentSenderRecords.size() > 0) {
5154                Iterator<WeakReference<PendingIntentRecord>> it
5155                        = mIntentSenderRecords.values().iterator();
5156                while (it.hasNext()) {
5157                    WeakReference<PendingIntentRecord> wpir = it.next();
5158                    if (wpir == null) {
5159                        it.remove();
5160                        continue;
5161                    }
5162                    PendingIntentRecord pir = wpir.get();
5163                    if (pir == null) {
5164                        it.remove();
5165                        continue;
5166                    }
5167                    if (name == null) {
5168                        // Stopping user, remove all objects for the user.
5169                        if (pir.key.userId != userId) {
5170                            // Not the same user, skip it.
5171                            continue;
5172                        }
5173                    } else {
5174                        if (UserHandle.getAppId(pir.uid) != appId) {
5175                            // Different app id, skip it.
5176                            continue;
5177                        }
5178                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5179                            // Different user, skip it.
5180                            continue;
5181                        }
5182                        if (!pir.key.packageName.equals(name)) {
5183                            // Different package, skip it.
5184                            continue;
5185                        }
5186                    }
5187                    if (!doit) {
5188                        return true;
5189                    }
5190                    didSomething = true;
5191                    it.remove();
5192                    pir.canceled = true;
5193                    if (pir.key.activity != null) {
5194                        pir.key.activity.pendingResults.remove(pir.ref);
5195                    }
5196                }
5197            }
5198        }
5199
5200        if (doit) {
5201            if (purgeCache && name != null) {
5202                AttributeCache ac = AttributeCache.instance();
5203                if (ac != null) {
5204                    ac.removePackage(name);
5205                }
5206            }
5207            if (mBooted) {
5208                mStackSupervisor.resumeTopActivitiesLocked();
5209                mStackSupervisor.scheduleIdleLocked();
5210            }
5211        }
5212
5213        return didSomething;
5214    }
5215
5216    private final boolean removeProcessLocked(ProcessRecord app,
5217            boolean callerWillRestart, boolean allowRestart, String reason) {
5218        final String name = app.processName;
5219        final int uid = app.uid;
5220        if (DEBUG_PROCESSES) Slog.d(
5221            TAG, "Force removing proc " + app.toShortString() + " (" + name
5222            + "/" + uid + ")");
5223
5224        mProcessNames.remove(name, uid);
5225        mIsolatedProcesses.remove(app.uid);
5226        if (mHeavyWeightProcess == app) {
5227            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5228                    mHeavyWeightProcess.userId, 0));
5229            mHeavyWeightProcess = null;
5230        }
5231        boolean needRestart = false;
5232        if (app.pid > 0 && app.pid != MY_PID) {
5233            int pid = app.pid;
5234            synchronized (mPidsSelfLocked) {
5235                mPidsSelfLocked.remove(pid);
5236                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5237            }
5238            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5239            if (app.isolated) {
5240                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5241            }
5242            killUnneededProcessLocked(app, reason);
5243            Process.killProcessGroup(app.info.uid, app.pid);
5244            handleAppDiedLocked(app, true, allowRestart);
5245            removeLruProcessLocked(app);
5246
5247            if (app.persistent && !app.isolated) {
5248                if (!callerWillRestart) {
5249                    addAppLocked(app.info, false, null /* ABI override */);
5250                } else {
5251                    needRestart = true;
5252                }
5253            }
5254        } else {
5255            mRemovedProcesses.add(app);
5256        }
5257
5258        return needRestart;
5259    }
5260
5261    private final void processStartTimedOutLocked(ProcessRecord app) {
5262        final int pid = app.pid;
5263        boolean gone = false;
5264        synchronized (mPidsSelfLocked) {
5265            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5266            if (knownApp != null && knownApp.thread == null) {
5267                mPidsSelfLocked.remove(pid);
5268                gone = true;
5269            }
5270        }
5271
5272        if (gone) {
5273            Slog.w(TAG, "Process " + app + " failed to attach");
5274            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5275                    pid, app.uid, app.processName);
5276            mProcessNames.remove(app.processName, app.uid);
5277            mIsolatedProcesses.remove(app.uid);
5278            if (mHeavyWeightProcess == app) {
5279                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5280                        mHeavyWeightProcess.userId, 0));
5281                mHeavyWeightProcess = null;
5282            }
5283            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5284            if (app.isolated) {
5285                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5286            }
5287            // Take care of any launching providers waiting for this process.
5288            checkAppInLaunchingProvidersLocked(app, true);
5289            // Take care of any services that are waiting for the process.
5290            mServices.processStartTimedOutLocked(app);
5291            killUnneededProcessLocked(app, "start timeout");
5292            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5293                Slog.w(TAG, "Unattached app died before backup, skipping");
5294                try {
5295                    IBackupManager bm = IBackupManager.Stub.asInterface(
5296                            ServiceManager.getService(Context.BACKUP_SERVICE));
5297                    bm.agentDisconnected(app.info.packageName);
5298                } catch (RemoteException e) {
5299                    // Can't happen; the backup manager is local
5300                }
5301            }
5302            if (isPendingBroadcastProcessLocked(pid)) {
5303                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5304                skipPendingBroadcastLocked(pid);
5305            }
5306        } else {
5307            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5308        }
5309    }
5310
5311    private final boolean attachApplicationLocked(IApplicationThread thread,
5312            int pid) {
5313
5314        // Find the application record that is being attached...  either via
5315        // the pid if we are running in multiple processes, or just pull the
5316        // next app record if we are emulating process with anonymous threads.
5317        ProcessRecord app;
5318        if (pid != MY_PID && pid >= 0) {
5319            synchronized (mPidsSelfLocked) {
5320                app = mPidsSelfLocked.get(pid);
5321            }
5322        } else {
5323            app = null;
5324        }
5325
5326        if (app == null) {
5327            Slog.w(TAG, "No pending application record for pid " + pid
5328                    + " (IApplicationThread " + thread + "); dropping process");
5329            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5330            if (pid > 0 && pid != MY_PID) {
5331                Process.killProcessQuiet(pid);
5332                //TODO: Process.killProcessGroup(app.info.uid, pid);
5333            } else {
5334                try {
5335                    thread.scheduleExit();
5336                } catch (Exception e) {
5337                    // Ignore exceptions.
5338                }
5339            }
5340            return false;
5341        }
5342
5343        // If this application record is still attached to a previous
5344        // process, clean it up now.
5345        if (app.thread != null) {
5346            handleAppDiedLocked(app, true, true);
5347        }
5348
5349        // Tell the process all about itself.
5350
5351        if (localLOGV) Slog.v(
5352                TAG, "Binding process pid " + pid + " to record " + app);
5353
5354        final String processName = app.processName;
5355        try {
5356            AppDeathRecipient adr = new AppDeathRecipient(
5357                    app, pid, thread);
5358            thread.asBinder().linkToDeath(adr, 0);
5359            app.deathRecipient = adr;
5360        } catch (RemoteException e) {
5361            app.resetPackageList(mProcessStats);
5362            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5363            return false;
5364        }
5365
5366        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5367
5368        app.makeActive(thread, mProcessStats);
5369        app.curAdj = app.setAdj = -100;
5370        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5371        app.forcingToForeground = null;
5372        updateProcessForegroundLocked(app, false, false);
5373        app.hasShownUi = false;
5374        app.debugging = false;
5375        app.cached = false;
5376
5377        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5378
5379        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5380        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5381
5382        if (!normalMode) {
5383            Slog.i(TAG, "Launching preboot mode app: " + app);
5384        }
5385
5386        if (localLOGV) Slog.v(
5387            TAG, "New app record " + app
5388            + " thread=" + thread.asBinder() + " pid=" + pid);
5389        try {
5390            int testMode = IApplicationThread.DEBUG_OFF;
5391            if (mDebugApp != null && mDebugApp.equals(processName)) {
5392                testMode = mWaitForDebugger
5393                    ? IApplicationThread.DEBUG_WAIT
5394                    : IApplicationThread.DEBUG_ON;
5395                app.debugging = true;
5396                if (mDebugTransient) {
5397                    mDebugApp = mOrigDebugApp;
5398                    mWaitForDebugger = mOrigWaitForDebugger;
5399                }
5400            }
5401            String profileFile = app.instrumentationProfileFile;
5402            ParcelFileDescriptor profileFd = null;
5403            boolean profileAutoStop = false;
5404            if (mProfileApp != null && mProfileApp.equals(processName)) {
5405                mProfileProc = app;
5406                profileFile = mProfileFile;
5407                profileFd = mProfileFd;
5408                profileAutoStop = mAutoStopProfiler;
5409            }
5410            boolean enableOpenGlTrace = false;
5411            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5412                enableOpenGlTrace = true;
5413                mOpenGlTraceApp = null;
5414            }
5415
5416            // If the app is being launched for restore or full backup, set it up specially
5417            boolean isRestrictedBackupMode = false;
5418            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5419                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5420                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5421                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5422            }
5423
5424            ensurePackageDexOpt(app.instrumentationInfo != null
5425                    ? app.instrumentationInfo.packageName
5426                    : app.info.packageName);
5427            if (app.instrumentationClass != null) {
5428                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5429            }
5430            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5431                    + processName + " with config " + mConfiguration);
5432            ApplicationInfo appInfo = app.instrumentationInfo != null
5433                    ? app.instrumentationInfo : app.info;
5434            app.compat = compatibilityInfoForPackageLocked(appInfo);
5435            if (profileFd != null) {
5436                profileFd = profileFd.dup();
5437            }
5438            thread.bindApplication(processName, appInfo, providers,
5439                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5440                    app.instrumentationArguments, app.instrumentationWatcher,
5441                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5442                    isRestrictedBackupMode || !normalMode, app.persistent,
5443                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5444                    mCoreSettingsObserver.getCoreSettingsLocked());
5445            updateLruProcessLocked(app, false, null);
5446            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5447        } catch (Exception e) {
5448            // todo: Yikes!  What should we do?  For now we will try to
5449            // start another process, but that could easily get us in
5450            // an infinite loop of restarting processes...
5451            Slog.w(TAG, "Exception thrown during bind!", e);
5452
5453            app.resetPackageList(mProcessStats);
5454            app.unlinkDeathRecipient();
5455            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5456            return false;
5457        }
5458
5459        // Remove this record from the list of starting applications.
5460        mPersistentStartingProcesses.remove(app);
5461        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5462                "Attach application locked removing on hold: " + app);
5463        mProcessesOnHold.remove(app);
5464
5465        boolean badApp = false;
5466        boolean didSomething = false;
5467
5468        // See if the top visible activity is waiting to run in this process...
5469        if (normalMode) {
5470            try {
5471                if (mStackSupervisor.attachApplicationLocked(app)) {
5472                    didSomething = true;
5473                }
5474            } catch (Exception e) {
5475                badApp = true;
5476            }
5477        }
5478
5479        // Find any services that should be running in this process...
5480        if (!badApp) {
5481            try {
5482                didSomething |= mServices.attachApplicationLocked(app, processName);
5483            } catch (Exception e) {
5484                badApp = true;
5485            }
5486        }
5487
5488        // Check if a next-broadcast receiver is in this process...
5489        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5490            try {
5491                didSomething |= sendPendingBroadcastsLocked(app);
5492            } catch (Exception e) {
5493                // If the app died trying to launch the receiver we declare it 'bad'
5494                badApp = true;
5495            }
5496        }
5497
5498        // Check whether the next backup agent is in this process...
5499        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5500            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5501            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5502            try {
5503                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5504                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5505                        mBackupTarget.backupMode);
5506            } catch (Exception e) {
5507                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5508                e.printStackTrace();
5509            }
5510        }
5511
5512        if (badApp) {
5513            // todo: Also need to kill application to deal with all
5514            // kinds of exceptions.
5515            handleAppDiedLocked(app, false, true);
5516            return false;
5517        }
5518
5519        if (!didSomething) {
5520            updateOomAdjLocked();
5521        }
5522
5523        return true;
5524    }
5525
5526    @Override
5527    public final void attachApplication(IApplicationThread thread) {
5528        synchronized (this) {
5529            int callingPid = Binder.getCallingPid();
5530            final long origId = Binder.clearCallingIdentity();
5531            attachApplicationLocked(thread, callingPid);
5532            Binder.restoreCallingIdentity(origId);
5533        }
5534    }
5535
5536    @Override
5537    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5538        final long origId = Binder.clearCallingIdentity();
5539        synchronized (this) {
5540            ActivityStack stack = ActivityRecord.getStackLocked(token);
5541            if (stack != null) {
5542                ActivityRecord r =
5543                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5544                if (stopProfiling) {
5545                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5546                        try {
5547                            mProfileFd.close();
5548                        } catch (IOException e) {
5549                        }
5550                        clearProfilerLocked();
5551                    }
5552                }
5553            }
5554        }
5555        Binder.restoreCallingIdentity(origId);
5556    }
5557
5558    void postEnableScreenAfterBootLocked() {
5559        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5560    }
5561
5562    void enableScreenAfterBoot() {
5563        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5564                SystemClock.uptimeMillis());
5565        mWindowManager.enableScreenAfterBoot();
5566
5567        synchronized (this) {
5568            updateEventDispatchingLocked();
5569        }
5570    }
5571
5572    @Override
5573    public void showBootMessage(final CharSequence msg, final boolean always) {
5574        enforceNotIsolatedCaller("showBootMessage");
5575        mWindowManager.showBootMessage(msg, always);
5576    }
5577
5578    @Override
5579    public void dismissKeyguardOnNextActivity() {
5580        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5581        final long token = Binder.clearCallingIdentity();
5582        try {
5583            synchronized (this) {
5584                if (DEBUG_LOCKSCREEN) logLockScreen("");
5585                if (mLockScreenShown) {
5586                    mLockScreenShown = false;
5587                    comeOutOfSleepIfNeededLocked();
5588                }
5589                mStackSupervisor.setDismissKeyguard(true);
5590            }
5591        } finally {
5592            Binder.restoreCallingIdentity(token);
5593        }
5594    }
5595
5596    final void finishBooting() {
5597        // Register receivers to handle package update events
5598        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5599
5600        synchronized (this) {
5601            // Ensure that any processes we had put on hold are now started
5602            // up.
5603            final int NP = mProcessesOnHold.size();
5604            if (NP > 0) {
5605                ArrayList<ProcessRecord> procs =
5606                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5607                for (int ip=0; ip<NP; ip++) {
5608                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5609                            + procs.get(ip));
5610                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5611                }
5612            }
5613
5614            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5615                // Start looking for apps that are abusing wake locks.
5616                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5617                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5618                // Tell anyone interested that we are done booting!
5619                SystemProperties.set("sys.boot_completed", "1");
5620                SystemProperties.set("dev.bootcomplete", "1");
5621                for (int i=0; i<mStartedUsers.size(); i++) {
5622                    UserStartedState uss = mStartedUsers.valueAt(i);
5623                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5624                        uss.mState = UserStartedState.STATE_RUNNING;
5625                        final int userId = mStartedUsers.keyAt(i);
5626                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5627                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5628                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5629                        broadcastIntentLocked(null, null, intent, null,
5630                                new IIntentReceiver.Stub() {
5631                                    @Override
5632                                    public void performReceive(Intent intent, int resultCode,
5633                                            String data, Bundle extras, boolean ordered,
5634                                            boolean sticky, int sendingUser) {
5635                                        synchronized (ActivityManagerService.this) {
5636                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5637                                                    true, false);
5638                                        }
5639                                    }
5640                                },
5641                                0, null, null,
5642                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5643                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5644                                userId);
5645                    }
5646                }
5647                scheduleStartProfilesLocked();
5648            }
5649        }
5650    }
5651
5652    final void ensureBootCompleted() {
5653        boolean booting;
5654        boolean enableScreen;
5655        synchronized (this) {
5656            booting = mBooting;
5657            mBooting = false;
5658            enableScreen = !mBooted;
5659            mBooted = true;
5660        }
5661
5662        if (booting) {
5663            finishBooting();
5664        }
5665
5666        if (enableScreen) {
5667            enableScreenAfterBoot();
5668        }
5669    }
5670
5671    @Override
5672    public final void activityResumed(IBinder token) {
5673        final long origId = Binder.clearCallingIdentity();
5674        synchronized(this) {
5675            ActivityStack stack = ActivityRecord.getStackLocked(token);
5676            if (stack != null) {
5677                ActivityRecord.activityResumedLocked(token);
5678            }
5679        }
5680        Binder.restoreCallingIdentity(origId);
5681    }
5682
5683    @Override
5684    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5685        final long origId = Binder.clearCallingIdentity();
5686        synchronized(this) {
5687            ActivityStack stack = ActivityRecord.getStackLocked(token);
5688            if (stack != null) {
5689                stack.activityPausedLocked(token, false, persistentState);
5690            }
5691        }
5692        Binder.restoreCallingIdentity(origId);
5693    }
5694
5695    @Override
5696    public final void activityStopped(IBinder token, Bundle icicle,
5697            PersistableBundle persistentState, CharSequence description) {
5698        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5699
5700        // Refuse possible leaked file descriptors
5701        if (icicle != null && icicle.hasFileDescriptors()) {
5702            throw new IllegalArgumentException("File descriptors passed in Bundle");
5703        }
5704
5705        final long origId = Binder.clearCallingIdentity();
5706
5707        synchronized (this) {
5708            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5709            if (r != null) {
5710                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5711            }
5712        }
5713
5714        trimApplications();
5715
5716        Binder.restoreCallingIdentity(origId);
5717    }
5718
5719    @Override
5720    public final void activityDestroyed(IBinder token) {
5721        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5722        synchronized (this) {
5723            ActivityStack stack = ActivityRecord.getStackLocked(token);
5724            if (stack != null) {
5725                stack.activityDestroyedLocked(token);
5726            }
5727        }
5728    }
5729
5730    @Override
5731    public final void mediaResourcesReleased(IBinder token) {
5732        final long origId = Binder.clearCallingIdentity();
5733        try {
5734            synchronized (this) {
5735                ActivityStack stack = ActivityRecord.getStackLocked(token);
5736                if (stack != null) {
5737                    stack.mediaResourcesReleased(token);
5738                }
5739            }
5740        } finally {
5741            Binder.restoreCallingIdentity(origId);
5742        }
5743    }
5744
5745    @Override
5746    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5747        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5748    }
5749
5750    @Override
5751    public final void notifyEnterAnimationComplete(IBinder token) {
5752        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5753    }
5754
5755    @Override
5756    public String getCallingPackage(IBinder token) {
5757        synchronized (this) {
5758            ActivityRecord r = getCallingRecordLocked(token);
5759            return r != null ? r.info.packageName : null;
5760        }
5761    }
5762
5763    @Override
5764    public ComponentName getCallingActivity(IBinder token) {
5765        synchronized (this) {
5766            ActivityRecord r = getCallingRecordLocked(token);
5767            return r != null ? r.intent.getComponent() : null;
5768        }
5769    }
5770
5771    private ActivityRecord getCallingRecordLocked(IBinder token) {
5772        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5773        if (r == null) {
5774            return null;
5775        }
5776        return r.resultTo;
5777    }
5778
5779    @Override
5780    public ComponentName getActivityClassForToken(IBinder token) {
5781        synchronized(this) {
5782            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5783            if (r == null) {
5784                return null;
5785            }
5786            return r.intent.getComponent();
5787        }
5788    }
5789
5790    @Override
5791    public String getPackageForToken(IBinder token) {
5792        synchronized(this) {
5793            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5794            if (r == null) {
5795                return null;
5796            }
5797            return r.packageName;
5798        }
5799    }
5800
5801    @Override
5802    public IIntentSender getIntentSender(int type,
5803            String packageName, IBinder token, String resultWho,
5804            int requestCode, Intent[] intents, String[] resolvedTypes,
5805            int flags, Bundle options, int userId) {
5806        enforceNotIsolatedCaller("getIntentSender");
5807        // Refuse possible leaked file descriptors
5808        if (intents != null) {
5809            if (intents.length < 1) {
5810                throw new IllegalArgumentException("Intents array length must be >= 1");
5811            }
5812            for (int i=0; i<intents.length; i++) {
5813                Intent intent = intents[i];
5814                if (intent != null) {
5815                    if (intent.hasFileDescriptors()) {
5816                        throw new IllegalArgumentException("File descriptors passed in Intent");
5817                    }
5818                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5819                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5820                        throw new IllegalArgumentException(
5821                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5822                    }
5823                    intents[i] = new Intent(intent);
5824                }
5825            }
5826            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5827                throw new IllegalArgumentException(
5828                        "Intent array length does not match resolvedTypes length");
5829            }
5830        }
5831        if (options != null) {
5832            if (options.hasFileDescriptors()) {
5833                throw new IllegalArgumentException("File descriptors passed in options");
5834            }
5835        }
5836
5837        synchronized(this) {
5838            int callingUid = Binder.getCallingUid();
5839            int origUserId = userId;
5840            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5841                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5842                    ALLOW_NON_FULL, "getIntentSender", null);
5843            if (origUserId == UserHandle.USER_CURRENT) {
5844                // We don't want to evaluate this until the pending intent is
5845                // actually executed.  However, we do want to always do the
5846                // security checking for it above.
5847                userId = UserHandle.USER_CURRENT;
5848            }
5849            try {
5850                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5851                    int uid = AppGlobals.getPackageManager()
5852                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5853                    if (!UserHandle.isSameApp(callingUid, uid)) {
5854                        String msg = "Permission Denial: getIntentSender() from pid="
5855                            + Binder.getCallingPid()
5856                            + ", uid=" + Binder.getCallingUid()
5857                            + ", (need uid=" + uid + ")"
5858                            + " is not allowed to send as package " + packageName;
5859                        Slog.w(TAG, msg);
5860                        throw new SecurityException(msg);
5861                    }
5862                }
5863
5864                return getIntentSenderLocked(type, packageName, callingUid, userId,
5865                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5866
5867            } catch (RemoteException e) {
5868                throw new SecurityException(e);
5869            }
5870        }
5871    }
5872
5873    IIntentSender getIntentSenderLocked(int type, String packageName,
5874            int callingUid, int userId, IBinder token, String resultWho,
5875            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5876            Bundle options) {
5877        if (DEBUG_MU)
5878            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5879        ActivityRecord activity = null;
5880        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5881            activity = ActivityRecord.isInStackLocked(token);
5882            if (activity == null) {
5883                return null;
5884            }
5885            if (activity.finishing) {
5886                return null;
5887            }
5888        }
5889
5890        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5891        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5892        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5893        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5894                |PendingIntent.FLAG_UPDATE_CURRENT);
5895
5896        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5897                type, packageName, activity, resultWho,
5898                requestCode, intents, resolvedTypes, flags, options, userId);
5899        WeakReference<PendingIntentRecord> ref;
5900        ref = mIntentSenderRecords.get(key);
5901        PendingIntentRecord rec = ref != null ? ref.get() : null;
5902        if (rec != null) {
5903            if (!cancelCurrent) {
5904                if (updateCurrent) {
5905                    if (rec.key.requestIntent != null) {
5906                        rec.key.requestIntent.replaceExtras(intents != null ?
5907                                intents[intents.length - 1] : null);
5908                    }
5909                    if (intents != null) {
5910                        intents[intents.length-1] = rec.key.requestIntent;
5911                        rec.key.allIntents = intents;
5912                        rec.key.allResolvedTypes = resolvedTypes;
5913                    } else {
5914                        rec.key.allIntents = null;
5915                        rec.key.allResolvedTypes = null;
5916                    }
5917                }
5918                return rec;
5919            }
5920            rec.canceled = true;
5921            mIntentSenderRecords.remove(key);
5922        }
5923        if (noCreate) {
5924            return rec;
5925        }
5926        rec = new PendingIntentRecord(this, key, callingUid);
5927        mIntentSenderRecords.put(key, rec.ref);
5928        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5929            if (activity.pendingResults == null) {
5930                activity.pendingResults
5931                        = new HashSet<WeakReference<PendingIntentRecord>>();
5932            }
5933            activity.pendingResults.add(rec.ref);
5934        }
5935        return rec;
5936    }
5937
5938    @Override
5939    public void cancelIntentSender(IIntentSender sender) {
5940        if (!(sender instanceof PendingIntentRecord)) {
5941            return;
5942        }
5943        synchronized(this) {
5944            PendingIntentRecord rec = (PendingIntentRecord)sender;
5945            try {
5946                int uid = AppGlobals.getPackageManager()
5947                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5948                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5949                    String msg = "Permission Denial: cancelIntentSender() from pid="
5950                        + Binder.getCallingPid()
5951                        + ", uid=" + Binder.getCallingUid()
5952                        + " is not allowed to cancel packges "
5953                        + rec.key.packageName;
5954                    Slog.w(TAG, msg);
5955                    throw new SecurityException(msg);
5956                }
5957            } catch (RemoteException e) {
5958                throw new SecurityException(e);
5959            }
5960            cancelIntentSenderLocked(rec, true);
5961        }
5962    }
5963
5964    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5965        rec.canceled = true;
5966        mIntentSenderRecords.remove(rec.key);
5967        if (cleanActivity && rec.key.activity != null) {
5968            rec.key.activity.pendingResults.remove(rec.ref);
5969        }
5970    }
5971
5972    @Override
5973    public String getPackageForIntentSender(IIntentSender pendingResult) {
5974        if (!(pendingResult instanceof PendingIntentRecord)) {
5975            return null;
5976        }
5977        try {
5978            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5979            return res.key.packageName;
5980        } catch (ClassCastException e) {
5981        }
5982        return null;
5983    }
5984
5985    @Override
5986    public int getUidForIntentSender(IIntentSender sender) {
5987        if (sender instanceof PendingIntentRecord) {
5988            try {
5989                PendingIntentRecord res = (PendingIntentRecord)sender;
5990                return res.uid;
5991            } catch (ClassCastException e) {
5992            }
5993        }
5994        return -1;
5995    }
5996
5997    @Override
5998    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5999        if (!(pendingResult instanceof PendingIntentRecord)) {
6000            return false;
6001        }
6002        try {
6003            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6004            if (res.key.allIntents == null) {
6005                return false;
6006            }
6007            for (int i=0; i<res.key.allIntents.length; i++) {
6008                Intent intent = res.key.allIntents[i];
6009                if (intent.getPackage() != null && intent.getComponent() != null) {
6010                    return false;
6011                }
6012            }
6013            return true;
6014        } catch (ClassCastException e) {
6015        }
6016        return false;
6017    }
6018
6019    @Override
6020    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6021        if (!(pendingResult instanceof PendingIntentRecord)) {
6022            return false;
6023        }
6024        try {
6025            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6026            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6027                return true;
6028            }
6029            return false;
6030        } catch (ClassCastException e) {
6031        }
6032        return false;
6033    }
6034
6035    @Override
6036    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6037        if (!(pendingResult instanceof PendingIntentRecord)) {
6038            return null;
6039        }
6040        try {
6041            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6042            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6043        } catch (ClassCastException e) {
6044        }
6045        return null;
6046    }
6047
6048    @Override
6049    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6050        if (!(pendingResult instanceof PendingIntentRecord)) {
6051            return null;
6052        }
6053        try {
6054            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6055            Intent intent = res.key.requestIntent;
6056            if (intent != null) {
6057                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6058                        || res.lastTagPrefix.equals(prefix))) {
6059                    return res.lastTag;
6060                }
6061                res.lastTagPrefix = prefix;
6062                StringBuilder sb = new StringBuilder(128);
6063                if (prefix != null) {
6064                    sb.append(prefix);
6065                }
6066                if (intent.getAction() != null) {
6067                    sb.append(intent.getAction());
6068                } else if (intent.getComponent() != null) {
6069                    intent.getComponent().appendShortString(sb);
6070                } else {
6071                    sb.append("?");
6072                }
6073                return res.lastTag = sb.toString();
6074            }
6075        } catch (ClassCastException e) {
6076        }
6077        return null;
6078    }
6079
6080    @Override
6081    public void setProcessLimit(int max) {
6082        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6083                "setProcessLimit()");
6084        synchronized (this) {
6085            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6086            mProcessLimitOverride = max;
6087        }
6088        trimApplications();
6089    }
6090
6091    @Override
6092    public int getProcessLimit() {
6093        synchronized (this) {
6094            return mProcessLimitOverride;
6095        }
6096    }
6097
6098    void foregroundTokenDied(ForegroundToken token) {
6099        synchronized (ActivityManagerService.this) {
6100            synchronized (mPidsSelfLocked) {
6101                ForegroundToken cur
6102                    = mForegroundProcesses.get(token.pid);
6103                if (cur != token) {
6104                    return;
6105                }
6106                mForegroundProcesses.remove(token.pid);
6107                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6108                if (pr == null) {
6109                    return;
6110                }
6111                pr.forcingToForeground = null;
6112                updateProcessForegroundLocked(pr, false, false);
6113            }
6114            updateOomAdjLocked();
6115        }
6116    }
6117
6118    @Override
6119    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6120        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6121                "setProcessForeground()");
6122        synchronized(this) {
6123            boolean changed = false;
6124
6125            synchronized (mPidsSelfLocked) {
6126                ProcessRecord pr = mPidsSelfLocked.get(pid);
6127                if (pr == null && isForeground) {
6128                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6129                    return;
6130                }
6131                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6132                if (oldToken != null) {
6133                    oldToken.token.unlinkToDeath(oldToken, 0);
6134                    mForegroundProcesses.remove(pid);
6135                    if (pr != null) {
6136                        pr.forcingToForeground = null;
6137                    }
6138                    changed = true;
6139                }
6140                if (isForeground && token != null) {
6141                    ForegroundToken newToken = new ForegroundToken() {
6142                        @Override
6143                        public void binderDied() {
6144                            foregroundTokenDied(this);
6145                        }
6146                    };
6147                    newToken.pid = pid;
6148                    newToken.token = token;
6149                    try {
6150                        token.linkToDeath(newToken, 0);
6151                        mForegroundProcesses.put(pid, newToken);
6152                        pr.forcingToForeground = token;
6153                        changed = true;
6154                    } catch (RemoteException e) {
6155                        // If the process died while doing this, we will later
6156                        // do the cleanup with the process death link.
6157                    }
6158                }
6159            }
6160
6161            if (changed) {
6162                updateOomAdjLocked();
6163            }
6164        }
6165    }
6166
6167    // =========================================================
6168    // PERMISSIONS
6169    // =========================================================
6170
6171    static class PermissionController extends IPermissionController.Stub {
6172        ActivityManagerService mActivityManagerService;
6173        PermissionController(ActivityManagerService activityManagerService) {
6174            mActivityManagerService = activityManagerService;
6175        }
6176
6177        @Override
6178        public boolean checkPermission(String permission, int pid, int uid) {
6179            return mActivityManagerService.checkPermission(permission, pid,
6180                    uid) == PackageManager.PERMISSION_GRANTED;
6181        }
6182    }
6183
6184    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6185        @Override
6186        public int checkComponentPermission(String permission, int pid, int uid,
6187                int owningUid, boolean exported) {
6188            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6189                    owningUid, exported);
6190        }
6191
6192        @Override
6193        public Object getAMSLock() {
6194            return ActivityManagerService.this;
6195        }
6196    }
6197
6198    /**
6199     * This can be called with or without the global lock held.
6200     */
6201    int checkComponentPermission(String permission, int pid, int uid,
6202            int owningUid, boolean exported) {
6203        // We might be performing an operation on behalf of an indirect binder
6204        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6205        // client identity accordingly before proceeding.
6206        Identity tlsIdentity = sCallerIdentity.get();
6207        if (tlsIdentity != null) {
6208            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6209                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6210            uid = tlsIdentity.uid;
6211            pid = tlsIdentity.pid;
6212        }
6213
6214        if (pid == MY_PID) {
6215            return PackageManager.PERMISSION_GRANTED;
6216        }
6217
6218        return ActivityManager.checkComponentPermission(permission, uid,
6219                owningUid, exported);
6220    }
6221
6222    /**
6223     * As the only public entry point for permissions checking, this method
6224     * can enforce the semantic that requesting a check on a null global
6225     * permission is automatically denied.  (Internally a null permission
6226     * string is used when calling {@link #checkComponentPermission} in cases
6227     * when only uid-based security is needed.)
6228     *
6229     * This can be called with or without the global lock held.
6230     */
6231    @Override
6232    public int checkPermission(String permission, int pid, int uid) {
6233        if (permission == null) {
6234            return PackageManager.PERMISSION_DENIED;
6235        }
6236        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6237    }
6238
6239    /**
6240     * Binder IPC calls go through the public entry point.
6241     * This can be called with or without the global lock held.
6242     */
6243    int checkCallingPermission(String permission) {
6244        return checkPermission(permission,
6245                Binder.getCallingPid(),
6246                UserHandle.getAppId(Binder.getCallingUid()));
6247    }
6248
6249    /**
6250     * This can be called with or without the global lock held.
6251     */
6252    void enforceCallingPermission(String permission, String func) {
6253        if (checkCallingPermission(permission)
6254                == PackageManager.PERMISSION_GRANTED) {
6255            return;
6256        }
6257
6258        String msg = "Permission Denial: " + func + " from pid="
6259                + Binder.getCallingPid()
6260                + ", uid=" + Binder.getCallingUid()
6261                + " requires " + permission;
6262        Slog.w(TAG, msg);
6263        throw new SecurityException(msg);
6264    }
6265
6266    /**
6267     * Determine if UID is holding permissions required to access {@link Uri} in
6268     * the given {@link ProviderInfo}. Final permission checking is always done
6269     * in {@link ContentProvider}.
6270     */
6271    private final boolean checkHoldingPermissionsLocked(
6272            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6273        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6274                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6275        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6276            return false;
6277        }
6278        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6279    }
6280
6281    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6282            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6283        if (pi.applicationInfo.uid == uid) {
6284            return true;
6285        } else if (!pi.exported) {
6286            return false;
6287        }
6288
6289        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6290        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6291        try {
6292            // check if target holds top-level <provider> permissions
6293            if (!readMet && pi.readPermission != null && considerUidPermissions
6294                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6295                readMet = true;
6296            }
6297            if (!writeMet && pi.writePermission != null && considerUidPermissions
6298                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6299                writeMet = true;
6300            }
6301
6302            // track if unprotected read/write is allowed; any denied
6303            // <path-permission> below removes this ability
6304            boolean allowDefaultRead = pi.readPermission == null;
6305            boolean allowDefaultWrite = pi.writePermission == null;
6306
6307            // check if target holds any <path-permission> that match uri
6308            final PathPermission[] pps = pi.pathPermissions;
6309            if (pps != null) {
6310                final String path = grantUri.uri.getPath();
6311                int i = pps.length;
6312                while (i > 0 && (!readMet || !writeMet)) {
6313                    i--;
6314                    PathPermission pp = pps[i];
6315                    if (pp.match(path)) {
6316                        if (!readMet) {
6317                            final String pprperm = pp.getReadPermission();
6318                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6319                                    + pprperm + " for " + pp.getPath()
6320                                    + ": match=" + pp.match(path)
6321                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6322                            if (pprperm != null) {
6323                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6324                                        == PERMISSION_GRANTED) {
6325                                    readMet = true;
6326                                } else {
6327                                    allowDefaultRead = false;
6328                                }
6329                            }
6330                        }
6331                        if (!writeMet) {
6332                            final String ppwperm = pp.getWritePermission();
6333                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6334                                    + ppwperm + " for " + pp.getPath()
6335                                    + ": match=" + pp.match(path)
6336                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6337                            if (ppwperm != null) {
6338                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6339                                        == PERMISSION_GRANTED) {
6340                                    writeMet = true;
6341                                } else {
6342                                    allowDefaultWrite = false;
6343                                }
6344                            }
6345                        }
6346                    }
6347                }
6348            }
6349
6350            // grant unprotected <provider> read/write, if not blocked by
6351            // <path-permission> above
6352            if (allowDefaultRead) readMet = true;
6353            if (allowDefaultWrite) writeMet = true;
6354
6355        } catch (RemoteException e) {
6356            return false;
6357        }
6358
6359        return readMet && writeMet;
6360    }
6361
6362    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6363        ProviderInfo pi = null;
6364        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6365        if (cpr != null) {
6366            pi = cpr.info;
6367        } else {
6368            try {
6369                pi = AppGlobals.getPackageManager().resolveContentProvider(
6370                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6371            } catch (RemoteException ex) {
6372            }
6373        }
6374        return pi;
6375    }
6376
6377    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6378        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6379        if (targetUris != null) {
6380            return targetUris.get(grantUri);
6381        }
6382        return null;
6383    }
6384
6385    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6386            String targetPkg, int targetUid, GrantUri grantUri) {
6387        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6388        if (targetUris == null) {
6389            targetUris = Maps.newArrayMap();
6390            mGrantedUriPermissions.put(targetUid, targetUris);
6391        }
6392
6393        UriPermission perm = targetUris.get(grantUri);
6394        if (perm == null) {
6395            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6396            targetUris.put(grantUri, perm);
6397        }
6398
6399        return perm;
6400    }
6401
6402    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6403            final int modeFlags) {
6404        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6405        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6406                : UriPermission.STRENGTH_OWNED;
6407
6408        // Root gets to do everything.
6409        if (uid == 0) {
6410            return true;
6411        }
6412
6413        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6414        if (perms == null) return false;
6415
6416        // First look for exact match
6417        final UriPermission exactPerm = perms.get(grantUri);
6418        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6419            return true;
6420        }
6421
6422        // No exact match, look for prefixes
6423        final int N = perms.size();
6424        for (int i = 0; i < N; i++) {
6425            final UriPermission perm = perms.valueAt(i);
6426            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6427                    && perm.getStrength(modeFlags) >= minStrength) {
6428                return true;
6429            }
6430        }
6431
6432        return false;
6433    }
6434
6435    @Override
6436    public int checkUriPermission(Uri uri, int pid, int uid,
6437            final int modeFlags, int userId) {
6438        enforceNotIsolatedCaller("checkUriPermission");
6439
6440        // Another redirected-binder-call permissions check as in
6441        // {@link checkComponentPermission}.
6442        Identity tlsIdentity = sCallerIdentity.get();
6443        if (tlsIdentity != null) {
6444            uid = tlsIdentity.uid;
6445            pid = tlsIdentity.pid;
6446        }
6447
6448        // Our own process gets to do everything.
6449        if (pid == MY_PID) {
6450            return PackageManager.PERMISSION_GRANTED;
6451        }
6452        synchronized (this) {
6453            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6454                    ? PackageManager.PERMISSION_GRANTED
6455                    : PackageManager.PERMISSION_DENIED;
6456        }
6457    }
6458
6459    /**
6460     * Check if the targetPkg can be granted permission to access uri by
6461     * the callingUid using the given modeFlags.  Throws a security exception
6462     * if callingUid is not allowed to do this.  Returns the uid of the target
6463     * if the URI permission grant should be performed; returns -1 if it is not
6464     * needed (for example targetPkg already has permission to access the URI).
6465     * If you already know the uid of the target, you can supply it in
6466     * lastTargetUid else set that to -1.
6467     */
6468    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6469            final int modeFlags, int lastTargetUid) {
6470        if (!Intent.isAccessUriMode(modeFlags)) {
6471            return -1;
6472        }
6473
6474        if (targetPkg != null) {
6475            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6476                    "Checking grant " + targetPkg + " permission to " + grantUri);
6477        }
6478
6479        final IPackageManager pm = AppGlobals.getPackageManager();
6480
6481        // If this is not a content: uri, we can't do anything with it.
6482        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6483            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6484                    "Can't grant URI permission for non-content URI: " + grantUri);
6485            return -1;
6486        }
6487
6488        final String authority = grantUri.uri.getAuthority();
6489        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6490        if (pi == null) {
6491            Slog.w(TAG, "No content provider found for permission check: " +
6492                    grantUri.uri.toSafeString());
6493            return -1;
6494        }
6495
6496        int targetUid = lastTargetUid;
6497        if (targetUid < 0 && targetPkg != null) {
6498            try {
6499                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6500                if (targetUid < 0) {
6501                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6502                            "Can't grant URI permission no uid for: " + targetPkg);
6503                    return -1;
6504                }
6505            } catch (RemoteException ex) {
6506                return -1;
6507            }
6508        }
6509
6510        if (targetUid >= 0) {
6511            // First...  does the target actually need this permission?
6512            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6513                // No need to grant the target this permission.
6514                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6515                        "Target " + targetPkg + " already has full permission to " + grantUri);
6516                return -1;
6517            }
6518        } else {
6519            // First...  there is no target package, so can anyone access it?
6520            boolean allowed = pi.exported;
6521            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6522                if (pi.readPermission != null) {
6523                    allowed = false;
6524                }
6525            }
6526            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6527                if (pi.writePermission != null) {
6528                    allowed = false;
6529                }
6530            }
6531            if (allowed) {
6532                return -1;
6533            }
6534        }
6535
6536        /* There is a special cross user grant if:
6537         * - The target is on another user.
6538         * - Apps on the current user can access the uri without any uid permissions.
6539         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6540         * grant uri permissions.
6541         */
6542        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6543                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6544                modeFlags, false /*without considering the uid permissions*/);
6545
6546        // Second...  is the provider allowing granting of URI permissions?
6547        if (!specialCrossUserGrant) {
6548            if (!pi.grantUriPermissions) {
6549                throw new SecurityException("Provider " + pi.packageName
6550                        + "/" + pi.name
6551                        + " does not allow granting of Uri permissions (uri "
6552                        + grantUri + ")");
6553            }
6554            if (pi.uriPermissionPatterns != null) {
6555                final int N = pi.uriPermissionPatterns.length;
6556                boolean allowed = false;
6557                for (int i=0; i<N; i++) {
6558                    if (pi.uriPermissionPatterns[i] != null
6559                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6560                        allowed = true;
6561                        break;
6562                    }
6563                }
6564                if (!allowed) {
6565                    throw new SecurityException("Provider " + pi.packageName
6566                            + "/" + pi.name
6567                            + " does not allow granting of permission to path of Uri "
6568                            + grantUri);
6569                }
6570            }
6571        }
6572
6573        // Third...  does the caller itself have permission to access
6574        // this uri?
6575        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6576            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6577                // Require they hold a strong enough Uri permission
6578                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6579                    throw new SecurityException("Uid " + callingUid
6580                            + " does not have permission to uri " + grantUri);
6581                }
6582            }
6583        }
6584        return targetUid;
6585    }
6586
6587    @Override
6588    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6589            final int modeFlags, int userId) {
6590        enforceNotIsolatedCaller("checkGrantUriPermission");
6591        synchronized(this) {
6592            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6593                    new GrantUri(userId, uri, false), modeFlags, -1);
6594        }
6595    }
6596
6597    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6598            final int modeFlags, UriPermissionOwner owner) {
6599        if (!Intent.isAccessUriMode(modeFlags)) {
6600            return;
6601        }
6602
6603        // So here we are: the caller has the assumed permission
6604        // to the uri, and the target doesn't.  Let's now give this to
6605        // the target.
6606
6607        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6608                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6609
6610        final String authority = grantUri.uri.getAuthority();
6611        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6612        if (pi == null) {
6613            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6614            return;
6615        }
6616
6617        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6618            grantUri.prefix = true;
6619        }
6620        final UriPermission perm = findOrCreateUriPermissionLocked(
6621                pi.packageName, targetPkg, targetUid, grantUri);
6622        perm.grantModes(modeFlags, owner);
6623    }
6624
6625    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6626            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6627        if (targetPkg == null) {
6628            throw new NullPointerException("targetPkg");
6629        }
6630        int targetUid;
6631        final IPackageManager pm = AppGlobals.getPackageManager();
6632        try {
6633            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6634        } catch (RemoteException ex) {
6635            return;
6636        }
6637
6638        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6639                targetUid);
6640        if (targetUid < 0) {
6641            return;
6642        }
6643
6644        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6645                owner);
6646    }
6647
6648    static class NeededUriGrants extends ArrayList<GrantUri> {
6649        final String targetPkg;
6650        final int targetUid;
6651        final int flags;
6652
6653        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6654            this.targetPkg = targetPkg;
6655            this.targetUid = targetUid;
6656            this.flags = flags;
6657        }
6658    }
6659
6660    /**
6661     * Like checkGrantUriPermissionLocked, but takes an Intent.
6662     */
6663    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6664            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6665        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6666                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6667                + " clip=" + (intent != null ? intent.getClipData() : null)
6668                + " from " + intent + "; flags=0x"
6669                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6670
6671        if (targetPkg == null) {
6672            throw new NullPointerException("targetPkg");
6673        }
6674
6675        if (intent == null) {
6676            return null;
6677        }
6678        Uri data = intent.getData();
6679        ClipData clip = intent.getClipData();
6680        if (data == null && clip == null) {
6681            return null;
6682        }
6683        // Default userId for uris in the intent (if they don't specify it themselves)
6684        int contentUserHint = intent.getContentUserHint();
6685        if (contentUserHint == UserHandle.USER_CURRENT) {
6686            contentUserHint = UserHandle.getUserId(callingUid);
6687        }
6688        final IPackageManager pm = AppGlobals.getPackageManager();
6689        int targetUid;
6690        if (needed != null) {
6691            targetUid = needed.targetUid;
6692        } else {
6693            try {
6694                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6695            } catch (RemoteException ex) {
6696                return null;
6697            }
6698            if (targetUid < 0) {
6699                if (DEBUG_URI_PERMISSION) {
6700                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6701                            + " on user " + targetUserId);
6702                }
6703                return null;
6704            }
6705        }
6706        if (data != null) {
6707            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6708            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6709                    targetUid);
6710            if (targetUid > 0) {
6711                if (needed == null) {
6712                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6713                }
6714                needed.add(grantUri);
6715            }
6716        }
6717        if (clip != null) {
6718            for (int i=0; i<clip.getItemCount(); i++) {
6719                Uri uri = clip.getItemAt(i).getUri();
6720                if (uri != null) {
6721                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6722                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6723                            targetUid);
6724                    if (targetUid > 0) {
6725                        if (needed == null) {
6726                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6727                        }
6728                        needed.add(grantUri);
6729                    }
6730                } else {
6731                    Intent clipIntent = clip.getItemAt(i).getIntent();
6732                    if (clipIntent != null) {
6733                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6734                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6735                        if (newNeeded != null) {
6736                            needed = newNeeded;
6737                        }
6738                    }
6739                }
6740            }
6741        }
6742
6743        return needed;
6744    }
6745
6746    /**
6747     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6748     */
6749    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6750            UriPermissionOwner owner) {
6751        if (needed != null) {
6752            for (int i=0; i<needed.size(); i++) {
6753                GrantUri grantUri = needed.get(i);
6754                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6755                        grantUri, needed.flags, owner);
6756            }
6757        }
6758    }
6759
6760    void grantUriPermissionFromIntentLocked(int callingUid,
6761            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6762        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6763                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6764        if (needed == null) {
6765            return;
6766        }
6767
6768        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6769    }
6770
6771    @Override
6772    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6773            final int modeFlags, int userId) {
6774        enforceNotIsolatedCaller("grantUriPermission");
6775        GrantUri grantUri = new GrantUri(userId, uri, false);
6776        synchronized(this) {
6777            final ProcessRecord r = getRecordForAppLocked(caller);
6778            if (r == null) {
6779                throw new SecurityException("Unable to find app for caller "
6780                        + caller
6781                        + " when granting permission to uri " + grantUri);
6782            }
6783            if (targetPkg == null) {
6784                throw new IllegalArgumentException("null target");
6785            }
6786            if (grantUri == null) {
6787                throw new IllegalArgumentException("null uri");
6788            }
6789
6790            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6791                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6792                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6793                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6794
6795            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6796                    UserHandle.getUserId(r.uid));
6797        }
6798    }
6799
6800    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6801        if (perm.modeFlags == 0) {
6802            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6803                    perm.targetUid);
6804            if (perms != null) {
6805                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6806                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6807
6808                perms.remove(perm.uri);
6809                if (perms.isEmpty()) {
6810                    mGrantedUriPermissions.remove(perm.targetUid);
6811                }
6812            }
6813        }
6814    }
6815
6816    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6817        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6818
6819        final IPackageManager pm = AppGlobals.getPackageManager();
6820        final String authority = grantUri.uri.getAuthority();
6821        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6822        if (pi == null) {
6823            Slog.w(TAG, "No content provider found for permission revoke: "
6824                    + grantUri.toSafeString());
6825            return;
6826        }
6827
6828        // Does the caller have this permission on the URI?
6829        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6830            // Right now, if you are not the original owner of the permission,
6831            // you are not allowed to revoke it.
6832            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6833                throw new SecurityException("Uid " + callingUid
6834                        + " does not have permission to uri " + grantUri);
6835            //}
6836        }
6837
6838        boolean persistChanged = false;
6839
6840        // Go through all of the permissions and remove any that match.
6841        int N = mGrantedUriPermissions.size();
6842        for (int i = 0; i < N; i++) {
6843            final int targetUid = mGrantedUriPermissions.keyAt(i);
6844            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6845
6846            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6847                final UriPermission perm = it.next();
6848                if (perm.uri.sourceUserId == grantUri.sourceUserId
6849                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6850                    if (DEBUG_URI_PERMISSION)
6851                        Slog.v(TAG,
6852                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6853                    persistChanged |= perm.revokeModes(
6854                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6855                    if (perm.modeFlags == 0) {
6856                        it.remove();
6857                    }
6858                }
6859            }
6860
6861            if (perms.isEmpty()) {
6862                mGrantedUriPermissions.remove(targetUid);
6863                N--;
6864                i--;
6865            }
6866        }
6867
6868        if (persistChanged) {
6869            schedulePersistUriGrants();
6870        }
6871    }
6872
6873    @Override
6874    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6875            int userId) {
6876        enforceNotIsolatedCaller("revokeUriPermission");
6877        synchronized(this) {
6878            final ProcessRecord r = getRecordForAppLocked(caller);
6879            if (r == null) {
6880                throw new SecurityException("Unable to find app for caller "
6881                        + caller
6882                        + " when revoking permission to uri " + uri);
6883            }
6884            if (uri == null) {
6885                Slog.w(TAG, "revokeUriPermission: null uri");
6886                return;
6887            }
6888
6889            if (!Intent.isAccessUriMode(modeFlags)) {
6890                return;
6891            }
6892
6893            final IPackageManager pm = AppGlobals.getPackageManager();
6894            final String authority = uri.getAuthority();
6895            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6896            if (pi == null) {
6897                Slog.w(TAG, "No content provider found for permission revoke: "
6898                        + uri.toSafeString());
6899                return;
6900            }
6901
6902            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6903        }
6904    }
6905
6906    /**
6907     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6908     * given package.
6909     *
6910     * @param packageName Package name to match, or {@code null} to apply to all
6911     *            packages.
6912     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6913     *            to all users.
6914     * @param persistable If persistable grants should be removed.
6915     */
6916    private void removeUriPermissionsForPackageLocked(
6917            String packageName, int userHandle, boolean persistable) {
6918        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6919            throw new IllegalArgumentException("Must narrow by either package or user");
6920        }
6921
6922        boolean persistChanged = false;
6923
6924        int N = mGrantedUriPermissions.size();
6925        for (int i = 0; i < N; i++) {
6926            final int targetUid = mGrantedUriPermissions.keyAt(i);
6927            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6928
6929            // Only inspect grants matching user
6930            if (userHandle == UserHandle.USER_ALL
6931                    || userHandle == UserHandle.getUserId(targetUid)) {
6932                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6933                    final UriPermission perm = it.next();
6934
6935                    // Only inspect grants matching package
6936                    if (packageName == null || perm.sourcePkg.equals(packageName)
6937                            || perm.targetPkg.equals(packageName)) {
6938                        persistChanged |= perm.revokeModes(
6939                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6940
6941                        // Only remove when no modes remain; any persisted grants
6942                        // will keep this alive.
6943                        if (perm.modeFlags == 0) {
6944                            it.remove();
6945                        }
6946                    }
6947                }
6948
6949                if (perms.isEmpty()) {
6950                    mGrantedUriPermissions.remove(targetUid);
6951                    N--;
6952                    i--;
6953                }
6954            }
6955        }
6956
6957        if (persistChanged) {
6958            schedulePersistUriGrants();
6959        }
6960    }
6961
6962    @Override
6963    public IBinder newUriPermissionOwner(String name) {
6964        enforceNotIsolatedCaller("newUriPermissionOwner");
6965        synchronized(this) {
6966            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6967            return owner.getExternalTokenLocked();
6968        }
6969    }
6970
6971    @Override
6972    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6973            final int modeFlags, int sourceUserId, int targetUserId) {
6974        synchronized(this) {
6975            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6976            if (owner == null) {
6977                throw new IllegalArgumentException("Unknown owner: " + token);
6978            }
6979            if (fromUid != Binder.getCallingUid()) {
6980                if (Binder.getCallingUid() != Process.myUid()) {
6981                    // Only system code can grant URI permissions on behalf
6982                    // of other users.
6983                    throw new SecurityException("nice try");
6984                }
6985            }
6986            if (targetPkg == null) {
6987                throw new IllegalArgumentException("null target");
6988            }
6989            if (uri == null) {
6990                throw new IllegalArgumentException("null uri");
6991            }
6992
6993            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6994                    modeFlags, owner, targetUserId);
6995        }
6996    }
6997
6998    @Override
6999    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7000        synchronized(this) {
7001            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7002            if (owner == null) {
7003                throw new IllegalArgumentException("Unknown owner: " + token);
7004            }
7005
7006            if (uri == null) {
7007                owner.removeUriPermissionsLocked(mode);
7008            } else {
7009                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7010            }
7011        }
7012    }
7013
7014    private void schedulePersistUriGrants() {
7015        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7016            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7017                    10 * DateUtils.SECOND_IN_MILLIS);
7018        }
7019    }
7020
7021    private void writeGrantedUriPermissions() {
7022        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7023
7024        // Snapshot permissions so we can persist without lock
7025        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7026        synchronized (this) {
7027            final int size = mGrantedUriPermissions.size();
7028            for (int i = 0; i < size; i++) {
7029                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7030                for (UriPermission perm : perms.values()) {
7031                    if (perm.persistedModeFlags != 0) {
7032                        persist.add(perm.snapshot());
7033                    }
7034                }
7035            }
7036        }
7037
7038        FileOutputStream fos = null;
7039        try {
7040            fos = mGrantFile.startWrite();
7041
7042            XmlSerializer out = new FastXmlSerializer();
7043            out.setOutput(fos, "utf-8");
7044            out.startDocument(null, true);
7045            out.startTag(null, TAG_URI_GRANTS);
7046            for (UriPermission.Snapshot perm : persist) {
7047                out.startTag(null, TAG_URI_GRANT);
7048                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7049                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7050                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7051                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7052                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7053                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7054                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7055                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7056                out.endTag(null, TAG_URI_GRANT);
7057            }
7058            out.endTag(null, TAG_URI_GRANTS);
7059            out.endDocument();
7060
7061            mGrantFile.finishWrite(fos);
7062        } catch (IOException e) {
7063            if (fos != null) {
7064                mGrantFile.failWrite(fos);
7065            }
7066        }
7067    }
7068
7069    private void readGrantedUriPermissionsLocked() {
7070        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7071
7072        final long now = System.currentTimeMillis();
7073
7074        FileInputStream fis = null;
7075        try {
7076            fis = mGrantFile.openRead();
7077            final XmlPullParser in = Xml.newPullParser();
7078            in.setInput(fis, null);
7079
7080            int type;
7081            while ((type = in.next()) != END_DOCUMENT) {
7082                final String tag = in.getName();
7083                if (type == START_TAG) {
7084                    if (TAG_URI_GRANT.equals(tag)) {
7085                        final int sourceUserId;
7086                        final int targetUserId;
7087                        final int userHandle = readIntAttribute(in,
7088                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7089                        if (userHandle != UserHandle.USER_NULL) {
7090                            // For backwards compatibility.
7091                            sourceUserId = userHandle;
7092                            targetUserId = userHandle;
7093                        } else {
7094                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7095                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7096                        }
7097                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7098                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7099                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7100                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7101                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7102                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7103
7104                        // Sanity check that provider still belongs to source package
7105                        final ProviderInfo pi = getProviderInfoLocked(
7106                                uri.getAuthority(), sourceUserId);
7107                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7108                            int targetUid = -1;
7109                            try {
7110                                targetUid = AppGlobals.getPackageManager()
7111                                        .getPackageUid(targetPkg, targetUserId);
7112                            } catch (RemoteException e) {
7113                            }
7114                            if (targetUid != -1) {
7115                                final UriPermission perm = findOrCreateUriPermissionLocked(
7116                                        sourcePkg, targetPkg, targetUid,
7117                                        new GrantUri(sourceUserId, uri, prefix));
7118                                perm.initPersistedModes(modeFlags, createdTime);
7119                            }
7120                        } else {
7121                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7122                                    + " but instead found " + pi);
7123                        }
7124                    }
7125                }
7126            }
7127        } catch (FileNotFoundException e) {
7128            // Missing grants is okay
7129        } catch (IOException e) {
7130            Log.wtf(TAG, "Failed reading Uri grants", e);
7131        } catch (XmlPullParserException e) {
7132            Log.wtf(TAG, "Failed reading Uri grants", e);
7133        } finally {
7134            IoUtils.closeQuietly(fis);
7135        }
7136    }
7137
7138    @Override
7139    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7140        enforceNotIsolatedCaller("takePersistableUriPermission");
7141
7142        Preconditions.checkFlagsArgument(modeFlags,
7143                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7144
7145        synchronized (this) {
7146            final int callingUid = Binder.getCallingUid();
7147            boolean persistChanged = false;
7148            GrantUri grantUri = new GrantUri(userId, uri, false);
7149
7150            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7151                    new GrantUri(userId, uri, false));
7152            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7153                    new GrantUri(userId, uri, true));
7154
7155            final boolean exactValid = (exactPerm != null)
7156                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7157            final boolean prefixValid = (prefixPerm != null)
7158                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7159
7160            if (!(exactValid || prefixValid)) {
7161                throw new SecurityException("No persistable permission grants found for UID "
7162                        + callingUid + " and Uri " + grantUri.toSafeString());
7163            }
7164
7165            if (exactValid) {
7166                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7167            }
7168            if (prefixValid) {
7169                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7170            }
7171
7172            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7173
7174            if (persistChanged) {
7175                schedulePersistUriGrants();
7176            }
7177        }
7178    }
7179
7180    @Override
7181    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7182        enforceNotIsolatedCaller("releasePersistableUriPermission");
7183
7184        Preconditions.checkFlagsArgument(modeFlags,
7185                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7186
7187        synchronized (this) {
7188            final int callingUid = Binder.getCallingUid();
7189            boolean persistChanged = false;
7190
7191            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7192                    new GrantUri(userId, uri, false));
7193            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7194                    new GrantUri(userId, uri, true));
7195            if (exactPerm == null && prefixPerm == null) {
7196                throw new SecurityException("No permission grants found for UID " + callingUid
7197                        + " and Uri " + uri.toSafeString());
7198            }
7199
7200            if (exactPerm != null) {
7201                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7202                removeUriPermissionIfNeededLocked(exactPerm);
7203            }
7204            if (prefixPerm != null) {
7205                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7206                removeUriPermissionIfNeededLocked(prefixPerm);
7207            }
7208
7209            if (persistChanged) {
7210                schedulePersistUriGrants();
7211            }
7212        }
7213    }
7214
7215    /**
7216     * Prune any older {@link UriPermission} for the given UID until outstanding
7217     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7218     *
7219     * @return if any mutations occured that require persisting.
7220     */
7221    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7222        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7223        if (perms == null) return false;
7224        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7225
7226        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7227        for (UriPermission perm : perms.values()) {
7228            if (perm.persistedModeFlags != 0) {
7229                persisted.add(perm);
7230            }
7231        }
7232
7233        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7234        if (trimCount <= 0) return false;
7235
7236        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7237        for (int i = 0; i < trimCount; i++) {
7238            final UriPermission perm = persisted.get(i);
7239
7240            if (DEBUG_URI_PERMISSION) {
7241                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7242            }
7243
7244            perm.releasePersistableModes(~0);
7245            removeUriPermissionIfNeededLocked(perm);
7246        }
7247
7248        return true;
7249    }
7250
7251    @Override
7252    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7253            String packageName, boolean incoming) {
7254        enforceNotIsolatedCaller("getPersistedUriPermissions");
7255        Preconditions.checkNotNull(packageName, "packageName");
7256
7257        final int callingUid = Binder.getCallingUid();
7258        final IPackageManager pm = AppGlobals.getPackageManager();
7259        try {
7260            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7261            if (packageUid != callingUid) {
7262                throw new SecurityException(
7263                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7264            }
7265        } catch (RemoteException e) {
7266            throw new SecurityException("Failed to verify package name ownership");
7267        }
7268
7269        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7270        synchronized (this) {
7271            if (incoming) {
7272                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7273                        callingUid);
7274                if (perms == null) {
7275                    Slog.w(TAG, "No permission grants found for " + packageName);
7276                } else {
7277                    for (UriPermission perm : perms.values()) {
7278                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7279                            result.add(perm.buildPersistedPublicApiObject());
7280                        }
7281                    }
7282                }
7283            } else {
7284                final int size = mGrantedUriPermissions.size();
7285                for (int i = 0; i < size; i++) {
7286                    final ArrayMap<GrantUri, UriPermission> perms =
7287                            mGrantedUriPermissions.valueAt(i);
7288                    for (UriPermission perm : perms.values()) {
7289                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7290                            result.add(perm.buildPersistedPublicApiObject());
7291                        }
7292                    }
7293                }
7294            }
7295        }
7296        return new ParceledListSlice<android.content.UriPermission>(result);
7297    }
7298
7299    @Override
7300    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7301        synchronized (this) {
7302            ProcessRecord app =
7303                who != null ? getRecordForAppLocked(who) : null;
7304            if (app == null) return;
7305
7306            Message msg = Message.obtain();
7307            msg.what = WAIT_FOR_DEBUGGER_MSG;
7308            msg.obj = app;
7309            msg.arg1 = waiting ? 1 : 0;
7310            mHandler.sendMessage(msg);
7311        }
7312    }
7313
7314    @Override
7315    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7316        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7317        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7318        outInfo.availMem = Process.getFreeMemory();
7319        outInfo.totalMem = Process.getTotalMemory();
7320        outInfo.threshold = homeAppMem;
7321        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7322        outInfo.hiddenAppThreshold = cachedAppMem;
7323        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7324                ProcessList.SERVICE_ADJ);
7325        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7326                ProcessList.VISIBLE_APP_ADJ);
7327        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7328                ProcessList.FOREGROUND_APP_ADJ);
7329    }
7330
7331    // =========================================================
7332    // TASK MANAGEMENT
7333    // =========================================================
7334
7335    @Override
7336    public List<IAppTask> getAppTasks() {
7337        final PackageManager pm = mContext.getPackageManager();
7338        int callingUid = Binder.getCallingUid();
7339        long ident = Binder.clearCallingIdentity();
7340
7341        // Compose the list of packages for this id to test against
7342        HashSet<String> packages = new HashSet<String>();
7343        String[] uidPackages = pm.getPackagesForUid(callingUid);
7344        for (int i = 0; i < uidPackages.length; i++) {
7345            packages.add(uidPackages[i]);
7346        }
7347
7348        synchronized(this) {
7349            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7350            try {
7351                if (localLOGV) Slog.v(TAG, "getAppTasks");
7352
7353                final int N = mRecentTasks.size();
7354                for (int i = 0; i < N; i++) {
7355                    TaskRecord tr = mRecentTasks.get(i);
7356                    // Skip tasks that are not created by the caller
7357                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7358                        ActivityManager.RecentTaskInfo taskInfo =
7359                                createRecentTaskInfoFromTaskRecord(tr);
7360                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7361                        list.add(taskImpl);
7362                    }
7363                }
7364            } finally {
7365                Binder.restoreCallingIdentity(ident);
7366            }
7367            return list;
7368        }
7369    }
7370
7371    @Override
7372    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7373        final int callingUid = Binder.getCallingUid();
7374        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7375
7376        synchronized(this) {
7377            if (localLOGV) Slog.v(
7378                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7379
7380            final boolean allowed = checkCallingPermission(
7381                    android.Manifest.permission.GET_TASKS)
7382                    == PackageManager.PERMISSION_GRANTED;
7383            if (!allowed) {
7384                Slog.w(TAG, "getTasks: caller " + callingUid
7385                        + " does not hold GET_TASKS; limiting output");
7386            }
7387
7388            // TODO: Improve with MRU list from all ActivityStacks.
7389            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7390        }
7391
7392        return list;
7393    }
7394
7395    TaskRecord getMostRecentTask() {
7396        return mRecentTasks.get(0);
7397    }
7398
7399    /**
7400     * Creates a new RecentTaskInfo from a TaskRecord.
7401     */
7402    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7403        // Update the task description to reflect any changes in the task stack
7404        tr.updateTaskDescription();
7405
7406        // Compose the recent task info
7407        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7408        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7409        rti.persistentId = tr.taskId;
7410        rti.baseIntent = new Intent(tr.getBaseIntent());
7411        rti.origActivity = tr.origActivity;
7412        rti.description = tr.lastDescription;
7413        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7414        rti.userId = tr.userId;
7415        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7416        rti.firstActiveTime = tr.firstActiveTime;
7417        rti.lastActiveTime = tr.lastActiveTime;
7418        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7419        return rti;
7420    }
7421
7422    @Override
7423    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7424        final int callingUid = Binder.getCallingUid();
7425        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7426                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7427
7428        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7429        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7430        synchronized (this) {
7431            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7432                    == PackageManager.PERMISSION_GRANTED;
7433            if (!allowed) {
7434                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7435                        + " does not hold GET_TASKS; limiting output");
7436            }
7437            final boolean detailed = checkCallingPermission(
7438                    android.Manifest.permission.GET_DETAILED_TASKS)
7439                    == PackageManager.PERMISSION_GRANTED;
7440
7441            IPackageManager pm = AppGlobals.getPackageManager();
7442
7443            final int N = mRecentTasks.size();
7444            ArrayList<ActivityManager.RecentTaskInfo> res
7445                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7446                            maxNum < N ? maxNum : N);
7447
7448            final Set<Integer> includedUsers;
7449            if (includeProfiles) {
7450                includedUsers = getProfileIdsLocked(userId);
7451            } else {
7452                includedUsers = new HashSet<Integer>();
7453            }
7454            includedUsers.add(Integer.valueOf(userId));
7455
7456            // Regroup affiliated tasks together.
7457            for (int i = 0; i < N; ) {
7458                TaskRecord task = mRecentTasks.remove(i);
7459                if (mTmpRecents.contains(task)) {
7460                    continue;
7461                }
7462                int affiliatedTaskId = task.mAffiliatedTaskId;
7463                while (true) {
7464                    TaskRecord next = task.mNextAffiliate;
7465                    if (next == null) {
7466                        break;
7467                    }
7468                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7469                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7470                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7471                        task.setNextAffiliate(null);
7472                        if (next.mPrevAffiliate == task) {
7473                            next.setPrevAffiliate(null);
7474                        }
7475                        break;
7476                    }
7477                    if (next.mPrevAffiliate != task) {
7478                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7479                                next.mPrevAffiliate + " task=" + task);
7480                        next.setPrevAffiliate(null);
7481                        break;
7482                    }
7483                    if (!mRecentTasks.contains(next)) {
7484                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7485                        task.setNextAffiliate(null);
7486                        if (next.mPrevAffiliate == task) {
7487                            next.setPrevAffiliate(null);
7488                        }
7489                        break;
7490                    }
7491                    task = next;
7492                }
7493                // task is now the end of the list
7494                do {
7495                    mRecentTasks.remove(task);
7496                    mRecentTasks.add(i++, task);
7497                    mTmpRecents.add(task);
7498                } while ((task = task.mPrevAffiliate) != null);
7499            }
7500            mTmpRecents.clear();
7501            // mRecentTasks is now in sorted, affiliated order.
7502
7503            for (int i=0; i<N && maxNum > 0; i++) {
7504                TaskRecord tr = mRecentTasks.get(i);
7505                // Only add calling user or related users recent tasks
7506                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7507
7508                // Return the entry if desired by the caller.  We always return
7509                // the first entry, because callers always expect this to be the
7510                // foreground app.  We may filter others if the caller has
7511                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7512                // we should exclude the entry.
7513
7514                if (i == 0
7515                        || withExcluded
7516                        || (tr.intent == null)
7517                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7518                                == 0)) {
7519                    if (!allowed) {
7520                        // If the caller doesn't have the GET_TASKS permission, then only
7521                        // allow them to see a small subset of tasks -- their own and home.
7522                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7523                            continue;
7524                        }
7525                    }
7526                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7527                        // Don't include auto remove tasks that are finished or finishing.
7528                        continue;
7529                    }
7530
7531                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7532                    if (!detailed) {
7533                        rti.baseIntent.replaceExtras((Bundle)null);
7534                    }
7535
7536                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7537                        // Check whether this activity is currently available.
7538                        try {
7539                            if (rti.origActivity != null) {
7540                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7541                                        == null) {
7542                                    continue;
7543                                }
7544                            } else if (rti.baseIntent != null) {
7545                                if (pm.queryIntentActivities(rti.baseIntent,
7546                                        null, 0, userId) == null) {
7547                                    continue;
7548                                }
7549                            }
7550                        } catch (RemoteException e) {
7551                            // Will never happen.
7552                        }
7553                    }
7554
7555                    res.add(rti);
7556                    maxNum--;
7557                }
7558            }
7559            return res;
7560        }
7561    }
7562
7563    private TaskRecord recentTaskForIdLocked(int id) {
7564        final int N = mRecentTasks.size();
7565            for (int i=0; i<N; i++) {
7566                TaskRecord tr = mRecentTasks.get(i);
7567                if (tr.taskId == id) {
7568                    return tr;
7569                }
7570            }
7571            return null;
7572    }
7573
7574    @Override
7575    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7576        synchronized (this) {
7577            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7578                    "getTaskThumbnail()");
7579            TaskRecord tr = recentTaskForIdLocked(id);
7580            if (tr != null) {
7581                return tr.getTaskThumbnailLocked();
7582            }
7583        }
7584        return null;
7585    }
7586
7587    @Override
7588    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7589        synchronized (this) {
7590            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7591            if (r != null) {
7592                r.taskDescription = td;
7593                r.task.updateTaskDescription();
7594            }
7595        }
7596    }
7597
7598    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7599        if (!pr.killedByAm) {
7600            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7601            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7602                    pr.processName, pr.setAdj, reason);
7603            pr.killedByAm = true;
7604            Process.killProcessQuiet(pr.pid);
7605            Process.killProcessGroup(pr.info.uid, pr.pid);
7606        }
7607    }
7608
7609    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7610        tr.disposeThumbnail();
7611        mRecentTasks.remove(tr);
7612        tr.closeRecentsChain();
7613        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7614        Intent baseIntent = new Intent(
7615                tr.intent != null ? tr.intent : tr.affinityIntent);
7616        ComponentName component = baseIntent.getComponent();
7617        if (component == null) {
7618            Slog.w(TAG, "Now component for base intent of task: " + tr);
7619            return;
7620        }
7621
7622        // Find any running services associated with this app.
7623        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7624
7625        if (killProcesses) {
7626            // Find any running processes associated with this app.
7627            final String pkg = component.getPackageName();
7628            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7629            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7630            for (int i=0; i<pmap.size(); i++) {
7631                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7632                for (int j=0; j<uids.size(); j++) {
7633                    ProcessRecord proc = uids.valueAt(j);
7634                    if (proc.userId != tr.userId) {
7635                        continue;
7636                    }
7637                    if (!proc.pkgList.containsKey(pkg)) {
7638                        continue;
7639                    }
7640                    procs.add(proc);
7641                }
7642            }
7643
7644            // Kill the running processes.
7645            for (int i=0; i<procs.size(); i++) {
7646                ProcessRecord pr = procs.get(i);
7647                if (pr == mHomeProcess) {
7648                    // Don't kill the home process along with tasks from the same package.
7649                    continue;
7650                }
7651                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7652                    killUnneededProcessLocked(pr, "remove task");
7653                } else {
7654                    pr.waitingToKill = "remove task";
7655                }
7656            }
7657        }
7658    }
7659
7660    /**
7661     * Removes the task with the specified task id.
7662     *
7663     * @param taskId Identifier of the task to be removed.
7664     * @param flags Additional operational flags.  May be 0 or
7665     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7666     * @return Returns true if the given task was found and removed.
7667     */
7668    private boolean removeTaskByIdLocked(int taskId, int flags) {
7669        TaskRecord tr = recentTaskForIdLocked(taskId);
7670        if (tr != null) {
7671            tr.removeTaskActivitiesLocked();
7672            cleanUpRemovedTaskLocked(tr, flags);
7673            if (tr.isPersistable) {
7674                notifyTaskPersisterLocked(null, true);
7675            }
7676            return true;
7677        }
7678        return false;
7679    }
7680
7681    @Override
7682    public boolean removeTask(int taskId, int flags) {
7683        synchronized (this) {
7684            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7685                    "removeTask()");
7686            long ident = Binder.clearCallingIdentity();
7687            try {
7688                return removeTaskByIdLocked(taskId, flags);
7689            } finally {
7690                Binder.restoreCallingIdentity(ident);
7691            }
7692        }
7693    }
7694
7695    /**
7696     * TODO: Add mController hook
7697     */
7698    @Override
7699    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7700        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7701                "moveTaskToFront()");
7702
7703        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7704        synchronized(this) {
7705            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7706                    Binder.getCallingUid(), "Task to front")) {
7707                ActivityOptions.abort(options);
7708                return;
7709            }
7710            final long origId = Binder.clearCallingIdentity();
7711            try {
7712                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7713                if (task == null) {
7714                    return;
7715                }
7716                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7717                    mStackSupervisor.showLockTaskToast();
7718                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7719                    return;
7720                }
7721                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7722                if (prev != null && prev.isRecentsActivity()) {
7723                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7724                }
7725                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7726            } finally {
7727                Binder.restoreCallingIdentity(origId);
7728            }
7729            ActivityOptions.abort(options);
7730        }
7731    }
7732
7733    @Override
7734    public void moveTaskToBack(int taskId) {
7735        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7736                "moveTaskToBack()");
7737
7738        synchronized(this) {
7739            TaskRecord tr = recentTaskForIdLocked(taskId);
7740            if (tr != null) {
7741                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7742                ActivityStack stack = tr.stack;
7743                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7744                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7745                            Binder.getCallingUid(), "Task to back")) {
7746                        return;
7747                    }
7748                }
7749                final long origId = Binder.clearCallingIdentity();
7750                try {
7751                    stack.moveTaskToBackLocked(taskId, null);
7752                } finally {
7753                    Binder.restoreCallingIdentity(origId);
7754                }
7755            }
7756        }
7757    }
7758
7759    /**
7760     * Moves an activity, and all of the other activities within the same task, to the bottom
7761     * of the history stack.  The activity's order within the task is unchanged.
7762     *
7763     * @param token A reference to the activity we wish to move
7764     * @param nonRoot If false then this only works if the activity is the root
7765     *                of a task; if true it will work for any activity in a task.
7766     * @return Returns true if the move completed, false if not.
7767     */
7768    @Override
7769    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7770        enforceNotIsolatedCaller("moveActivityTaskToBack");
7771        synchronized(this) {
7772            final long origId = Binder.clearCallingIdentity();
7773            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7774            if (taskId >= 0) {
7775                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7776            }
7777            Binder.restoreCallingIdentity(origId);
7778        }
7779        return false;
7780    }
7781
7782    @Override
7783    public void moveTaskBackwards(int task) {
7784        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7785                "moveTaskBackwards()");
7786
7787        synchronized(this) {
7788            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7789                    Binder.getCallingUid(), "Task backwards")) {
7790                return;
7791            }
7792            final long origId = Binder.clearCallingIdentity();
7793            moveTaskBackwardsLocked(task);
7794            Binder.restoreCallingIdentity(origId);
7795        }
7796    }
7797
7798    private final void moveTaskBackwardsLocked(int task) {
7799        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7800    }
7801
7802    @Override
7803    public IBinder getHomeActivityToken() throws RemoteException {
7804        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7805                "getHomeActivityToken()");
7806        synchronized (this) {
7807            return mStackSupervisor.getHomeActivityToken();
7808        }
7809    }
7810
7811    @Override
7812    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7813            IActivityContainerCallback callback) throws RemoteException {
7814        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7815                "createActivityContainer()");
7816        synchronized (this) {
7817            if (parentActivityToken == null) {
7818                throw new IllegalArgumentException("parent token must not be null");
7819            }
7820            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7821            if (r == null) {
7822                return null;
7823            }
7824            if (callback == null) {
7825                throw new IllegalArgumentException("callback must not be null");
7826            }
7827            return mStackSupervisor.createActivityContainer(r, callback);
7828        }
7829    }
7830
7831    @Override
7832    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7833        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7834                "deleteActivityContainer()");
7835        synchronized (this) {
7836            mStackSupervisor.deleteActivityContainer(container);
7837        }
7838    }
7839
7840    @Override
7841    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7842            throws RemoteException {
7843        synchronized (this) {
7844            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7845            if (stack != null) {
7846                return stack.mActivityContainer;
7847            }
7848            return null;
7849        }
7850    }
7851
7852    @Override
7853    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7854        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7855                "moveTaskToStack()");
7856        if (stackId == HOME_STACK_ID) {
7857            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7858                    new RuntimeException("here").fillInStackTrace());
7859        }
7860        synchronized (this) {
7861            long ident = Binder.clearCallingIdentity();
7862            try {
7863                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7864                        + stackId + " toTop=" + toTop);
7865                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7866            } finally {
7867                Binder.restoreCallingIdentity(ident);
7868            }
7869        }
7870    }
7871
7872    @Override
7873    public void resizeStack(int stackBoxId, Rect bounds) {
7874        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7875                "resizeStackBox()");
7876        long ident = Binder.clearCallingIdentity();
7877        try {
7878            mWindowManager.resizeStack(stackBoxId, bounds);
7879        } finally {
7880            Binder.restoreCallingIdentity(ident);
7881        }
7882    }
7883
7884    @Override
7885    public List<StackInfo> getAllStackInfos() {
7886        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7887                "getAllStackInfos()");
7888        long ident = Binder.clearCallingIdentity();
7889        try {
7890            synchronized (this) {
7891                return mStackSupervisor.getAllStackInfosLocked();
7892            }
7893        } finally {
7894            Binder.restoreCallingIdentity(ident);
7895        }
7896    }
7897
7898    @Override
7899    public StackInfo getStackInfo(int stackId) {
7900        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7901                "getStackInfo()");
7902        long ident = Binder.clearCallingIdentity();
7903        try {
7904            synchronized (this) {
7905                return mStackSupervisor.getStackInfoLocked(stackId);
7906            }
7907        } finally {
7908            Binder.restoreCallingIdentity(ident);
7909        }
7910    }
7911
7912    @Override
7913    public boolean isInHomeStack(int taskId) {
7914        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7915                "getStackInfo()");
7916        long ident = Binder.clearCallingIdentity();
7917        try {
7918            synchronized (this) {
7919                TaskRecord tr = recentTaskForIdLocked(taskId);
7920                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7921            }
7922        } finally {
7923            Binder.restoreCallingIdentity(ident);
7924        }
7925    }
7926
7927    @Override
7928    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7929        synchronized(this) {
7930            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7931        }
7932    }
7933
7934    private boolean isLockTaskAuthorized(String pkg) {
7935        final DevicePolicyManager dpm = (DevicePolicyManager)
7936                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7937        try {
7938            int uid = mContext.getPackageManager().getPackageUid(pkg,
7939                    Binder.getCallingUserHandle().getIdentifier());
7940            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7941        } catch (NameNotFoundException e) {
7942            return false;
7943        }
7944    }
7945
7946    void startLockTaskMode(TaskRecord task) {
7947        final String pkg;
7948        synchronized (this) {
7949            pkg = task.intent.getComponent().getPackageName();
7950        }
7951        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7952        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7953            final TaskRecord taskRecord = task;
7954            mHandler.post(new Runnable() {
7955                @Override
7956                public void run() {
7957                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7958                }
7959            });
7960            return;
7961        }
7962        long ident = Binder.clearCallingIdentity();
7963        try {
7964            synchronized (this) {
7965                // Since we lost lock on task, make sure it is still there.
7966                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7967                if (task != null) {
7968                    if (!isSystemInitiated
7969                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7970                        throw new IllegalArgumentException("Invalid task, not in foreground");
7971                    }
7972                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7973                }
7974            }
7975        } finally {
7976            Binder.restoreCallingIdentity(ident);
7977        }
7978    }
7979
7980    @Override
7981    public void startLockTaskMode(int taskId) {
7982        final TaskRecord task;
7983        long ident = Binder.clearCallingIdentity();
7984        try {
7985            synchronized (this) {
7986                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7987            }
7988        } finally {
7989            Binder.restoreCallingIdentity(ident);
7990        }
7991        if (task != null) {
7992            startLockTaskMode(task);
7993        }
7994    }
7995
7996    @Override
7997    public void startLockTaskMode(IBinder token) {
7998        final TaskRecord task;
7999        long ident = Binder.clearCallingIdentity();
8000        try {
8001            synchronized (this) {
8002                final ActivityRecord r = ActivityRecord.forToken(token);
8003                if (r == null) {
8004                    return;
8005                }
8006                task = r.task;
8007            }
8008        } finally {
8009            Binder.restoreCallingIdentity(ident);
8010        }
8011        if (task != null) {
8012            startLockTaskMode(task);
8013        }
8014    }
8015
8016    @Override
8017    public void startLockTaskModeOnCurrent() throws RemoteException {
8018        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8019        ActivityRecord r = null;
8020        synchronized (this) {
8021            r = mStackSupervisor.topRunningActivityLocked();
8022        }
8023        startLockTaskMode(r.task);
8024    }
8025
8026    @Override
8027    public void stopLockTaskMode() {
8028        // Verify that the user matches the package of the intent for the TaskRecord
8029        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8030        // and stopLockTaskMode.
8031        final int callingUid = Binder.getCallingUid();
8032        if (callingUid != Process.SYSTEM_UID) {
8033            try {
8034                String pkg =
8035                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8036                int uid = mContext.getPackageManager().getPackageUid(pkg,
8037                        Binder.getCallingUserHandle().getIdentifier());
8038                if (uid != callingUid) {
8039                    throw new SecurityException("Invalid uid, expected " + uid);
8040                }
8041            } catch (NameNotFoundException e) {
8042                Log.d(TAG, "stopLockTaskMode " + e);
8043                return;
8044            }
8045        }
8046        long ident = Binder.clearCallingIdentity();
8047        try {
8048            Log.d(TAG, "stopLockTaskMode");
8049            // Stop lock task
8050            synchronized (this) {
8051                mStackSupervisor.setLockTaskModeLocked(null, false);
8052            }
8053        } finally {
8054            Binder.restoreCallingIdentity(ident);
8055        }
8056    }
8057
8058    @Override
8059    public void stopLockTaskModeOnCurrent() throws RemoteException {
8060        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8061        long ident = Binder.clearCallingIdentity();
8062        try {
8063            stopLockTaskMode();
8064        } finally {
8065            Binder.restoreCallingIdentity(ident);
8066        }
8067    }
8068
8069    @Override
8070    public boolean isInLockTaskMode() {
8071        synchronized (this) {
8072            return mStackSupervisor.isInLockTaskMode();
8073        }
8074    }
8075
8076    // =========================================================
8077    // CONTENT PROVIDERS
8078    // =========================================================
8079
8080    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8081        List<ProviderInfo> providers = null;
8082        try {
8083            providers = AppGlobals.getPackageManager().
8084                queryContentProviders(app.processName, app.uid,
8085                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8086        } catch (RemoteException ex) {
8087        }
8088        if (DEBUG_MU)
8089            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8090        int userId = app.userId;
8091        if (providers != null) {
8092            int N = providers.size();
8093            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8094            for (int i=0; i<N; i++) {
8095                ProviderInfo cpi =
8096                    (ProviderInfo)providers.get(i);
8097                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8098                        cpi.name, cpi.flags);
8099                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8100                    // This is a singleton provider, but a user besides the
8101                    // default user is asking to initialize a process it runs
8102                    // in...  well, no, it doesn't actually run in this process,
8103                    // it runs in the process of the default user.  Get rid of it.
8104                    providers.remove(i);
8105                    N--;
8106                    i--;
8107                    continue;
8108                }
8109
8110                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8111                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8112                if (cpr == null) {
8113                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8114                    mProviderMap.putProviderByClass(comp, cpr);
8115                }
8116                if (DEBUG_MU)
8117                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8118                app.pubProviders.put(cpi.name, cpr);
8119                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8120                    // Don't add this if it is a platform component that is marked
8121                    // to run in multiple processes, because this is actually
8122                    // part of the framework so doesn't make sense to track as a
8123                    // separate apk in the process.
8124                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8125                            mProcessStats);
8126                }
8127                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8128            }
8129        }
8130        return providers;
8131    }
8132
8133    /**
8134     * Check if {@link ProcessRecord} has a possible chance at accessing the
8135     * given {@link ProviderInfo}. Final permission checking is always done
8136     * in {@link ContentProvider}.
8137     */
8138    private final String checkContentProviderPermissionLocked(
8139            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8140        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8141        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8142        boolean checkedGrants = false;
8143        if (checkUser) {
8144            // Looking for cross-user grants before enforcing the typical cross-users permissions
8145            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8146            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8147                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8148                    return null;
8149                }
8150                checkedGrants = true;
8151            }
8152            userId = handleIncomingUser(callingPid, callingUid, userId,
8153                    false, ALLOW_NON_FULL,
8154                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8155            if (userId != tmpTargetUserId) {
8156                // When we actually went to determine the final targer user ID, this ended
8157                // up different than our initial check for the authority.  This is because
8158                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8159                // SELF.  So we need to re-check the grants again.
8160                checkedGrants = false;
8161            }
8162        }
8163        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8164                cpi.applicationInfo.uid, cpi.exported)
8165                == PackageManager.PERMISSION_GRANTED) {
8166            return null;
8167        }
8168        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8169                cpi.applicationInfo.uid, cpi.exported)
8170                == PackageManager.PERMISSION_GRANTED) {
8171            return null;
8172        }
8173
8174        PathPermission[] pps = cpi.pathPermissions;
8175        if (pps != null) {
8176            int i = pps.length;
8177            while (i > 0) {
8178                i--;
8179                PathPermission pp = pps[i];
8180                String pprperm = pp.getReadPermission();
8181                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8182                        cpi.applicationInfo.uid, cpi.exported)
8183                        == PackageManager.PERMISSION_GRANTED) {
8184                    return null;
8185                }
8186                String ppwperm = pp.getWritePermission();
8187                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8188                        cpi.applicationInfo.uid, cpi.exported)
8189                        == PackageManager.PERMISSION_GRANTED) {
8190                    return null;
8191                }
8192            }
8193        }
8194        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8195            return null;
8196        }
8197
8198        String msg;
8199        if (!cpi.exported) {
8200            msg = "Permission Denial: opening provider " + cpi.name
8201                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8202                    + ", uid=" + callingUid + ") that is not exported from uid "
8203                    + cpi.applicationInfo.uid;
8204        } else {
8205            msg = "Permission Denial: opening provider " + cpi.name
8206                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8207                    + ", uid=" + callingUid + ") requires "
8208                    + cpi.readPermission + " or " + cpi.writePermission;
8209        }
8210        Slog.w(TAG, msg);
8211        return msg;
8212    }
8213
8214    /**
8215     * Returns if the ContentProvider has granted a uri to callingUid
8216     */
8217    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8218        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8219        if (perms != null) {
8220            for (int i=perms.size()-1; i>=0; i--) {
8221                GrantUri grantUri = perms.keyAt(i);
8222                if (grantUri.sourceUserId == userId || !checkUser) {
8223                    if (matchesProvider(grantUri.uri, cpi)) {
8224                        return true;
8225                    }
8226                }
8227            }
8228        }
8229        return false;
8230    }
8231
8232    /**
8233     * Returns true if the uri authority is one of the authorities specified in the provider.
8234     */
8235    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8236        String uriAuth = uri.getAuthority();
8237        String cpiAuth = cpi.authority;
8238        if (cpiAuth.indexOf(';') == -1) {
8239            return cpiAuth.equals(uriAuth);
8240        }
8241        String[] cpiAuths = cpiAuth.split(";");
8242        int length = cpiAuths.length;
8243        for (int i = 0; i < length; i++) {
8244            if (cpiAuths[i].equals(uriAuth)) return true;
8245        }
8246        return false;
8247    }
8248
8249    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8250            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8251        if (r != null) {
8252            for (int i=0; i<r.conProviders.size(); i++) {
8253                ContentProviderConnection conn = r.conProviders.get(i);
8254                if (conn.provider == cpr) {
8255                    if (DEBUG_PROVIDER) Slog.v(TAG,
8256                            "Adding provider requested by "
8257                            + r.processName + " from process "
8258                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8259                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8260                    if (stable) {
8261                        conn.stableCount++;
8262                        conn.numStableIncs++;
8263                    } else {
8264                        conn.unstableCount++;
8265                        conn.numUnstableIncs++;
8266                    }
8267                    return conn;
8268                }
8269            }
8270            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8271            if (stable) {
8272                conn.stableCount = 1;
8273                conn.numStableIncs = 1;
8274            } else {
8275                conn.unstableCount = 1;
8276                conn.numUnstableIncs = 1;
8277            }
8278            cpr.connections.add(conn);
8279            r.conProviders.add(conn);
8280            return conn;
8281        }
8282        cpr.addExternalProcessHandleLocked(externalProcessToken);
8283        return null;
8284    }
8285
8286    boolean decProviderCountLocked(ContentProviderConnection conn,
8287            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8288        if (conn != null) {
8289            cpr = conn.provider;
8290            if (DEBUG_PROVIDER) Slog.v(TAG,
8291                    "Removing provider requested by "
8292                    + conn.client.processName + " from process "
8293                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8294                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8295            if (stable) {
8296                conn.stableCount--;
8297            } else {
8298                conn.unstableCount--;
8299            }
8300            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8301                cpr.connections.remove(conn);
8302                conn.client.conProviders.remove(conn);
8303                return true;
8304            }
8305            return false;
8306        }
8307        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8308        return false;
8309    }
8310
8311    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8312            String name, IBinder token, boolean stable, int userId) {
8313        ContentProviderRecord cpr;
8314        ContentProviderConnection conn = null;
8315        ProviderInfo cpi = null;
8316
8317        synchronized(this) {
8318            ProcessRecord r = null;
8319            if (caller != null) {
8320                r = getRecordForAppLocked(caller);
8321                if (r == null) {
8322                    throw new SecurityException(
8323                            "Unable to find app for caller " + caller
8324                          + " (pid=" + Binder.getCallingPid()
8325                          + ") when getting content provider " + name);
8326                }
8327            }
8328
8329            boolean checkCrossUser = true;
8330
8331            // First check if this content provider has been published...
8332            cpr = mProviderMap.getProviderByName(name, userId);
8333            // If that didn't work, check if it exists for user 0 and then
8334            // verify that it's a singleton provider before using it.
8335            if (cpr == null && userId != UserHandle.USER_OWNER) {
8336                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8337                if (cpr != null) {
8338                    cpi = cpr.info;
8339                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8340                            cpi.name, cpi.flags)
8341                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8342                        userId = UserHandle.USER_OWNER;
8343                        checkCrossUser = false;
8344                    } else {
8345                        cpr = null;
8346                        cpi = null;
8347                    }
8348                }
8349            }
8350
8351            boolean providerRunning = cpr != null;
8352            if (providerRunning) {
8353                cpi = cpr.info;
8354                String msg;
8355                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8356                        != null) {
8357                    throw new SecurityException(msg);
8358                }
8359
8360                if (r != null && cpr.canRunHere(r)) {
8361                    // This provider has been published or is in the process
8362                    // of being published...  but it is also allowed to run
8363                    // in the caller's process, so don't make a connection
8364                    // and just let the caller instantiate its own instance.
8365                    ContentProviderHolder holder = cpr.newHolder(null);
8366                    // don't give caller the provider object, it needs
8367                    // to make its own.
8368                    holder.provider = null;
8369                    return holder;
8370                }
8371
8372                final long origId = Binder.clearCallingIdentity();
8373
8374                // In this case the provider instance already exists, so we can
8375                // return it right away.
8376                conn = incProviderCountLocked(r, cpr, token, stable);
8377                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8378                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8379                        // If this is a perceptible app accessing the provider,
8380                        // make sure to count it as being accessed and thus
8381                        // back up on the LRU list.  This is good because
8382                        // content providers are often expensive to start.
8383                        updateLruProcessLocked(cpr.proc, false, null);
8384                    }
8385                }
8386
8387                if (cpr.proc != null) {
8388                    if (false) {
8389                        if (cpr.name.flattenToShortString().equals(
8390                                "com.android.providers.calendar/.CalendarProvider2")) {
8391                            Slog.v(TAG, "****************** KILLING "
8392                                + cpr.name.flattenToShortString());
8393                            Process.killProcess(cpr.proc.pid);
8394                        }
8395                    }
8396                    boolean success = updateOomAdjLocked(cpr.proc);
8397                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8398                    // NOTE: there is still a race here where a signal could be
8399                    // pending on the process even though we managed to update its
8400                    // adj level.  Not sure what to do about this, but at least
8401                    // the race is now smaller.
8402                    if (!success) {
8403                        // Uh oh...  it looks like the provider's process
8404                        // has been killed on us.  We need to wait for a new
8405                        // process to be started, and make sure its death
8406                        // doesn't kill our process.
8407                        Slog.i(TAG,
8408                                "Existing provider " + cpr.name.flattenToShortString()
8409                                + " is crashing; detaching " + r);
8410                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8411                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8412                        if (!lastRef) {
8413                            // This wasn't the last ref our process had on
8414                            // the provider...  we have now been killed, bail.
8415                            return null;
8416                        }
8417                        providerRunning = false;
8418                        conn = null;
8419                    }
8420                }
8421
8422                Binder.restoreCallingIdentity(origId);
8423            }
8424
8425            boolean singleton;
8426            if (!providerRunning) {
8427                try {
8428                    cpi = AppGlobals.getPackageManager().
8429                        resolveContentProvider(name,
8430                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8431                } catch (RemoteException ex) {
8432                }
8433                if (cpi == null) {
8434                    return null;
8435                }
8436                // If the provider is a singleton AND
8437                // (it's a call within the same user || the provider is a
8438                // privileged app)
8439                // Then allow connecting to the singleton provider
8440                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8441                        cpi.name, cpi.flags)
8442                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8443                if (singleton) {
8444                    userId = UserHandle.USER_OWNER;
8445                }
8446                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8447
8448                String msg;
8449                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8450                        != null) {
8451                    throw new SecurityException(msg);
8452                }
8453
8454                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8455                        && !cpi.processName.equals("system")) {
8456                    // If this content provider does not run in the system
8457                    // process, and the system is not yet ready to run other
8458                    // processes, then fail fast instead of hanging.
8459                    throw new IllegalArgumentException(
8460                            "Attempt to launch content provider before system ready");
8461                }
8462
8463                // Make sure that the user who owns this provider is started.  If not,
8464                // we don't want to allow it to run.
8465                if (mStartedUsers.get(userId) == null) {
8466                    Slog.w(TAG, "Unable to launch app "
8467                            + cpi.applicationInfo.packageName + "/"
8468                            + cpi.applicationInfo.uid + " for provider "
8469                            + name + ": user " + userId + " is stopped");
8470                    return null;
8471                }
8472
8473                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8474                cpr = mProviderMap.getProviderByClass(comp, userId);
8475                final boolean firstClass = cpr == null;
8476                if (firstClass) {
8477                    try {
8478                        ApplicationInfo ai =
8479                            AppGlobals.getPackageManager().
8480                                getApplicationInfo(
8481                                        cpi.applicationInfo.packageName,
8482                                        STOCK_PM_FLAGS, userId);
8483                        if (ai == null) {
8484                            Slog.w(TAG, "No package info for content provider "
8485                                    + cpi.name);
8486                            return null;
8487                        }
8488                        ai = getAppInfoForUser(ai, userId);
8489                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8490                    } catch (RemoteException ex) {
8491                        // pm is in same process, this will never happen.
8492                    }
8493                }
8494
8495                if (r != null && cpr.canRunHere(r)) {
8496                    // If this is a multiprocess provider, then just return its
8497                    // info and allow the caller to instantiate it.  Only do
8498                    // this if the provider is the same user as the caller's
8499                    // process, or can run as root (so can be in any process).
8500                    return cpr.newHolder(null);
8501                }
8502
8503                if (DEBUG_PROVIDER) {
8504                    RuntimeException e = new RuntimeException("here");
8505                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8506                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8507                }
8508
8509                // This is single process, and our app is now connecting to it.
8510                // See if we are already in the process of launching this
8511                // provider.
8512                final int N = mLaunchingProviders.size();
8513                int i;
8514                for (i=0; i<N; i++) {
8515                    if (mLaunchingProviders.get(i) == cpr) {
8516                        break;
8517                    }
8518                }
8519
8520                // If the provider is not already being launched, then get it
8521                // started.
8522                if (i >= N) {
8523                    final long origId = Binder.clearCallingIdentity();
8524
8525                    try {
8526                        // Content provider is now in use, its package can't be stopped.
8527                        try {
8528                            AppGlobals.getPackageManager().setPackageStoppedState(
8529                                    cpr.appInfo.packageName, false, userId);
8530                        } catch (RemoteException e) {
8531                        } catch (IllegalArgumentException e) {
8532                            Slog.w(TAG, "Failed trying to unstop package "
8533                                    + cpr.appInfo.packageName + ": " + e);
8534                        }
8535
8536                        // Use existing process if already started
8537                        ProcessRecord proc = getProcessRecordLocked(
8538                                cpi.processName, cpr.appInfo.uid, false);
8539                        if (proc != null && proc.thread != null) {
8540                            if (DEBUG_PROVIDER) {
8541                                Slog.d(TAG, "Installing in existing process " + proc);
8542                            }
8543                            proc.pubProviders.put(cpi.name, cpr);
8544                            try {
8545                                proc.thread.scheduleInstallProvider(cpi);
8546                            } catch (RemoteException e) {
8547                            }
8548                        } else {
8549                            proc = startProcessLocked(cpi.processName,
8550                                    cpr.appInfo, false, 0, "content provider",
8551                                    new ComponentName(cpi.applicationInfo.packageName,
8552                                            cpi.name), false, false, false);
8553                            if (proc == null) {
8554                                Slog.w(TAG, "Unable to launch app "
8555                                        + cpi.applicationInfo.packageName + "/"
8556                                        + cpi.applicationInfo.uid + " for provider "
8557                                        + name + ": process is bad");
8558                                return null;
8559                            }
8560                        }
8561                        cpr.launchingApp = proc;
8562                        mLaunchingProviders.add(cpr);
8563                    } finally {
8564                        Binder.restoreCallingIdentity(origId);
8565                    }
8566                }
8567
8568                // Make sure the provider is published (the same provider class
8569                // may be published under multiple names).
8570                if (firstClass) {
8571                    mProviderMap.putProviderByClass(comp, cpr);
8572                }
8573
8574                mProviderMap.putProviderByName(name, cpr);
8575                conn = incProviderCountLocked(r, cpr, token, stable);
8576                if (conn != null) {
8577                    conn.waiting = true;
8578                }
8579            }
8580        }
8581
8582        // Wait for the provider to be published...
8583        synchronized (cpr) {
8584            while (cpr.provider == null) {
8585                if (cpr.launchingApp == null) {
8586                    Slog.w(TAG, "Unable to launch app "
8587                            + cpi.applicationInfo.packageName + "/"
8588                            + cpi.applicationInfo.uid + " for provider "
8589                            + name + ": launching app became null");
8590                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8591                            UserHandle.getUserId(cpi.applicationInfo.uid),
8592                            cpi.applicationInfo.packageName,
8593                            cpi.applicationInfo.uid, name);
8594                    return null;
8595                }
8596                try {
8597                    if (DEBUG_MU) {
8598                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8599                                + cpr.launchingApp);
8600                    }
8601                    if (conn != null) {
8602                        conn.waiting = true;
8603                    }
8604                    cpr.wait();
8605                } catch (InterruptedException ex) {
8606                } finally {
8607                    if (conn != null) {
8608                        conn.waiting = false;
8609                    }
8610                }
8611            }
8612        }
8613        return cpr != null ? cpr.newHolder(conn) : null;
8614    }
8615
8616    @Override
8617    public final ContentProviderHolder getContentProvider(
8618            IApplicationThread caller, String name, int userId, boolean stable) {
8619        enforceNotIsolatedCaller("getContentProvider");
8620        if (caller == null) {
8621            String msg = "null IApplicationThread when getting content provider "
8622                    + name;
8623            Slog.w(TAG, msg);
8624            throw new SecurityException(msg);
8625        }
8626        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8627        // with cross-user grant.
8628        return getContentProviderImpl(caller, name, null, stable, userId);
8629    }
8630
8631    public ContentProviderHolder getContentProviderExternal(
8632            String name, int userId, IBinder token) {
8633        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8634            "Do not have permission in call getContentProviderExternal()");
8635        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8636                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8637        return getContentProviderExternalUnchecked(name, token, userId);
8638    }
8639
8640    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8641            IBinder token, int userId) {
8642        return getContentProviderImpl(null, name, token, true, userId);
8643    }
8644
8645    /**
8646     * Drop a content provider from a ProcessRecord's bookkeeping
8647     */
8648    public void removeContentProvider(IBinder connection, boolean stable) {
8649        enforceNotIsolatedCaller("removeContentProvider");
8650        long ident = Binder.clearCallingIdentity();
8651        try {
8652            synchronized (this) {
8653                ContentProviderConnection conn;
8654                try {
8655                    conn = (ContentProviderConnection)connection;
8656                } catch (ClassCastException e) {
8657                    String msg ="removeContentProvider: " + connection
8658                            + " not a ContentProviderConnection";
8659                    Slog.w(TAG, msg);
8660                    throw new IllegalArgumentException(msg);
8661                }
8662                if (conn == null) {
8663                    throw new NullPointerException("connection is null");
8664                }
8665                if (decProviderCountLocked(conn, null, null, stable)) {
8666                    updateOomAdjLocked();
8667                }
8668            }
8669        } finally {
8670            Binder.restoreCallingIdentity(ident);
8671        }
8672    }
8673
8674    public void removeContentProviderExternal(String name, IBinder token) {
8675        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8676            "Do not have permission in call removeContentProviderExternal()");
8677        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8678    }
8679
8680    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8681        synchronized (this) {
8682            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8683            if(cpr == null) {
8684                //remove from mProvidersByClass
8685                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8686                return;
8687            }
8688
8689            //update content provider record entry info
8690            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8691            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8692            if (localCpr.hasExternalProcessHandles()) {
8693                if (localCpr.removeExternalProcessHandleLocked(token)) {
8694                    updateOomAdjLocked();
8695                } else {
8696                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8697                            + " with no external reference for token: "
8698                            + token + ".");
8699                }
8700            } else {
8701                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8702                        + " with no external references.");
8703            }
8704        }
8705    }
8706
8707    public final void publishContentProviders(IApplicationThread caller,
8708            List<ContentProviderHolder> providers) {
8709        if (providers == null) {
8710            return;
8711        }
8712
8713        enforceNotIsolatedCaller("publishContentProviders");
8714        synchronized (this) {
8715            final ProcessRecord r = getRecordForAppLocked(caller);
8716            if (DEBUG_MU)
8717                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8718            if (r == null) {
8719                throw new SecurityException(
8720                        "Unable to find app for caller " + caller
8721                      + " (pid=" + Binder.getCallingPid()
8722                      + ") when publishing content providers");
8723            }
8724
8725            final long origId = Binder.clearCallingIdentity();
8726
8727            final int N = providers.size();
8728            for (int i=0; i<N; i++) {
8729                ContentProviderHolder src = providers.get(i);
8730                if (src == null || src.info == null || src.provider == null) {
8731                    continue;
8732                }
8733                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8734                if (DEBUG_MU)
8735                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8736                if (dst != null) {
8737                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8738                    mProviderMap.putProviderByClass(comp, dst);
8739                    String names[] = dst.info.authority.split(";");
8740                    for (int j = 0; j < names.length; j++) {
8741                        mProviderMap.putProviderByName(names[j], dst);
8742                    }
8743
8744                    int NL = mLaunchingProviders.size();
8745                    int j;
8746                    for (j=0; j<NL; j++) {
8747                        if (mLaunchingProviders.get(j) == dst) {
8748                            mLaunchingProviders.remove(j);
8749                            j--;
8750                            NL--;
8751                        }
8752                    }
8753                    synchronized (dst) {
8754                        dst.provider = src.provider;
8755                        dst.proc = r;
8756                        dst.notifyAll();
8757                    }
8758                    updateOomAdjLocked(r);
8759                }
8760            }
8761
8762            Binder.restoreCallingIdentity(origId);
8763        }
8764    }
8765
8766    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8767        ContentProviderConnection conn;
8768        try {
8769            conn = (ContentProviderConnection)connection;
8770        } catch (ClassCastException e) {
8771            String msg ="refContentProvider: " + connection
8772                    + " not a ContentProviderConnection";
8773            Slog.w(TAG, msg);
8774            throw new IllegalArgumentException(msg);
8775        }
8776        if (conn == null) {
8777            throw new NullPointerException("connection is null");
8778        }
8779
8780        synchronized (this) {
8781            if (stable > 0) {
8782                conn.numStableIncs += stable;
8783            }
8784            stable = conn.stableCount + stable;
8785            if (stable < 0) {
8786                throw new IllegalStateException("stableCount < 0: " + stable);
8787            }
8788
8789            if (unstable > 0) {
8790                conn.numUnstableIncs += unstable;
8791            }
8792            unstable = conn.unstableCount + unstable;
8793            if (unstable < 0) {
8794                throw new IllegalStateException("unstableCount < 0: " + unstable);
8795            }
8796
8797            if ((stable+unstable) <= 0) {
8798                throw new IllegalStateException("ref counts can't go to zero here: stable="
8799                        + stable + " unstable=" + unstable);
8800            }
8801            conn.stableCount = stable;
8802            conn.unstableCount = unstable;
8803            return !conn.dead;
8804        }
8805    }
8806
8807    public void unstableProviderDied(IBinder connection) {
8808        ContentProviderConnection conn;
8809        try {
8810            conn = (ContentProviderConnection)connection;
8811        } catch (ClassCastException e) {
8812            String msg ="refContentProvider: " + connection
8813                    + " not a ContentProviderConnection";
8814            Slog.w(TAG, msg);
8815            throw new IllegalArgumentException(msg);
8816        }
8817        if (conn == null) {
8818            throw new NullPointerException("connection is null");
8819        }
8820
8821        // Safely retrieve the content provider associated with the connection.
8822        IContentProvider provider;
8823        synchronized (this) {
8824            provider = conn.provider.provider;
8825        }
8826
8827        if (provider == null) {
8828            // Um, yeah, we're way ahead of you.
8829            return;
8830        }
8831
8832        // Make sure the caller is being honest with us.
8833        if (provider.asBinder().pingBinder()) {
8834            // Er, no, still looks good to us.
8835            synchronized (this) {
8836                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8837                        + " says " + conn + " died, but we don't agree");
8838                return;
8839            }
8840        }
8841
8842        // Well look at that!  It's dead!
8843        synchronized (this) {
8844            if (conn.provider.provider != provider) {
8845                // But something changed...  good enough.
8846                return;
8847            }
8848
8849            ProcessRecord proc = conn.provider.proc;
8850            if (proc == null || proc.thread == null) {
8851                // Seems like the process is already cleaned up.
8852                return;
8853            }
8854
8855            // As far as we're concerned, this is just like receiving a
8856            // death notification...  just a bit prematurely.
8857            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8858                    + ") early provider death");
8859            final long ident = Binder.clearCallingIdentity();
8860            try {
8861                appDiedLocked(proc, proc.pid, proc.thread);
8862            } finally {
8863                Binder.restoreCallingIdentity(ident);
8864            }
8865        }
8866    }
8867
8868    @Override
8869    public void appNotRespondingViaProvider(IBinder connection) {
8870        enforceCallingPermission(
8871                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8872
8873        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8874        if (conn == null) {
8875            Slog.w(TAG, "ContentProviderConnection is null");
8876            return;
8877        }
8878
8879        final ProcessRecord host = conn.provider.proc;
8880        if (host == null) {
8881            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8882            return;
8883        }
8884
8885        final long token = Binder.clearCallingIdentity();
8886        try {
8887            appNotResponding(host, null, null, false, "ContentProvider not responding");
8888        } finally {
8889            Binder.restoreCallingIdentity(token);
8890        }
8891    }
8892
8893    public final void installSystemProviders() {
8894        List<ProviderInfo> providers;
8895        synchronized (this) {
8896            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8897            providers = generateApplicationProvidersLocked(app);
8898            if (providers != null) {
8899                for (int i=providers.size()-1; i>=0; i--) {
8900                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8901                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8902                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8903                                + ": not system .apk");
8904                        providers.remove(i);
8905                    }
8906                }
8907            }
8908        }
8909        if (providers != null) {
8910            mSystemThread.installSystemProviders(providers);
8911        }
8912
8913        mCoreSettingsObserver = new CoreSettingsObserver(this);
8914
8915        //mUsageStatsService.monitorPackages();
8916    }
8917
8918    /**
8919     * Allows app to retrieve the MIME type of a URI without having permission
8920     * to access its content provider.
8921     *
8922     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8923     *
8924     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8925     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8926     */
8927    public String getProviderMimeType(Uri uri, int userId) {
8928        enforceNotIsolatedCaller("getProviderMimeType");
8929        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8930                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8931        final String name = uri.getAuthority();
8932        final long ident = Binder.clearCallingIdentity();
8933        ContentProviderHolder holder = null;
8934
8935        try {
8936            holder = getContentProviderExternalUnchecked(name, null, userId);
8937            if (holder != null) {
8938                return holder.provider.getType(uri);
8939            }
8940        } catch (RemoteException e) {
8941            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8942            return null;
8943        } finally {
8944            if (holder != null) {
8945                removeContentProviderExternalUnchecked(name, null, userId);
8946            }
8947            Binder.restoreCallingIdentity(ident);
8948        }
8949
8950        return null;
8951    }
8952
8953    // =========================================================
8954    // GLOBAL MANAGEMENT
8955    // =========================================================
8956
8957    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8958            boolean isolated) {
8959        String proc = customProcess != null ? customProcess : info.processName;
8960        BatteryStatsImpl.Uid.Proc ps = null;
8961        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8962        int uid = info.uid;
8963        if (isolated) {
8964            int userId = UserHandle.getUserId(uid);
8965            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8966            while (true) {
8967                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8968                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8969                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8970                }
8971                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8972                mNextIsolatedProcessUid++;
8973                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8974                    // No process for this uid, use it.
8975                    break;
8976                }
8977                stepsLeft--;
8978                if (stepsLeft <= 0) {
8979                    return null;
8980                }
8981            }
8982        }
8983        return new ProcessRecord(stats, info, proc, uid);
8984    }
8985
8986    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8987            String abiOverride) {
8988        ProcessRecord app;
8989        if (!isolated) {
8990            app = getProcessRecordLocked(info.processName, info.uid, true);
8991        } else {
8992            app = null;
8993        }
8994
8995        if (app == null) {
8996            app = newProcessRecordLocked(info, null, isolated);
8997            mProcessNames.put(info.processName, app.uid, app);
8998            if (isolated) {
8999                mIsolatedProcesses.put(app.uid, app);
9000            }
9001            updateLruProcessLocked(app, false, null);
9002            updateOomAdjLocked();
9003        }
9004
9005        // This package really, really can not be stopped.
9006        try {
9007            AppGlobals.getPackageManager().setPackageStoppedState(
9008                    info.packageName, false, UserHandle.getUserId(app.uid));
9009        } catch (RemoteException e) {
9010        } catch (IllegalArgumentException e) {
9011            Slog.w(TAG, "Failed trying to unstop package "
9012                    + info.packageName + ": " + e);
9013        }
9014
9015        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9016                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9017            app.persistent = true;
9018            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9019        }
9020        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9021            mPersistentStartingProcesses.add(app);
9022            startProcessLocked(app, "added application", app.processName,
9023                    abiOverride);
9024        }
9025
9026        return app;
9027    }
9028
9029    public void unhandledBack() {
9030        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9031                "unhandledBack()");
9032
9033        synchronized(this) {
9034            final long origId = Binder.clearCallingIdentity();
9035            try {
9036                getFocusedStack().unhandledBackLocked();
9037            } finally {
9038                Binder.restoreCallingIdentity(origId);
9039            }
9040        }
9041    }
9042
9043    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9044        enforceNotIsolatedCaller("openContentUri");
9045        final int userId = UserHandle.getCallingUserId();
9046        String name = uri.getAuthority();
9047        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9048        ParcelFileDescriptor pfd = null;
9049        if (cph != null) {
9050            // We record the binder invoker's uid in thread-local storage before
9051            // going to the content provider to open the file.  Later, in the code
9052            // that handles all permissions checks, we look for this uid and use
9053            // that rather than the Activity Manager's own uid.  The effect is that
9054            // we do the check against the caller's permissions even though it looks
9055            // to the content provider like the Activity Manager itself is making
9056            // the request.
9057            sCallerIdentity.set(new Identity(
9058                    Binder.getCallingPid(), Binder.getCallingUid()));
9059            try {
9060                pfd = cph.provider.openFile(null, uri, "r", null);
9061            } catch (FileNotFoundException e) {
9062                // do nothing; pfd will be returned null
9063            } finally {
9064                // Ensure that whatever happens, we clean up the identity state
9065                sCallerIdentity.remove();
9066            }
9067
9068            // We've got the fd now, so we're done with the provider.
9069            removeContentProviderExternalUnchecked(name, null, userId);
9070        } else {
9071            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9072        }
9073        return pfd;
9074    }
9075
9076    // Actually is sleeping or shutting down or whatever else in the future
9077    // is an inactive state.
9078    public boolean isSleepingOrShuttingDown() {
9079        return mSleeping || mShuttingDown;
9080    }
9081
9082    public boolean isSleeping() {
9083        return mSleeping;
9084    }
9085
9086    void goingToSleep() {
9087        synchronized(this) {
9088            mWentToSleep = true;
9089            updateEventDispatchingLocked();
9090            goToSleepIfNeededLocked();
9091        }
9092    }
9093
9094    void finishRunningVoiceLocked() {
9095        if (mRunningVoice) {
9096            mRunningVoice = false;
9097            goToSleepIfNeededLocked();
9098        }
9099    }
9100
9101    void goToSleepIfNeededLocked() {
9102        if (mWentToSleep && !mRunningVoice) {
9103            if (!mSleeping) {
9104                mSleeping = true;
9105                mStackSupervisor.goingToSleepLocked();
9106
9107                // Initialize the wake times of all processes.
9108                checkExcessivePowerUsageLocked(false);
9109                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9110                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9111                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9112            }
9113        }
9114    }
9115
9116    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9117        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9118            // Never persist the home stack.
9119            return;
9120        }
9121        mTaskPersister.wakeup(task, flush);
9122    }
9123
9124    @Override
9125    public boolean shutdown(int timeout) {
9126        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9127                != PackageManager.PERMISSION_GRANTED) {
9128            throw new SecurityException("Requires permission "
9129                    + android.Manifest.permission.SHUTDOWN);
9130        }
9131
9132        boolean timedout = false;
9133
9134        synchronized(this) {
9135            mShuttingDown = true;
9136            updateEventDispatchingLocked();
9137            timedout = mStackSupervisor.shutdownLocked(timeout);
9138        }
9139
9140        mAppOpsService.shutdown();
9141        if (mUsageStatsService != null) {
9142            mUsageStatsService.prepareShutdown();
9143        }
9144        mBatteryStatsService.shutdown();
9145        synchronized (this) {
9146            mProcessStats.shutdownLocked();
9147        }
9148        notifyTaskPersisterLocked(null, true);
9149
9150        return timedout;
9151    }
9152
9153    public final void activitySlept(IBinder token) {
9154        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9155
9156        final long origId = Binder.clearCallingIdentity();
9157
9158        synchronized (this) {
9159            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9160            if (r != null) {
9161                mStackSupervisor.activitySleptLocked(r);
9162            }
9163        }
9164
9165        Binder.restoreCallingIdentity(origId);
9166    }
9167
9168    void logLockScreen(String msg) {
9169        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9170                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9171                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9172                mStackSupervisor.mDismissKeyguardOnNextActivity);
9173    }
9174
9175    private void comeOutOfSleepIfNeededLocked() {
9176        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9177            if (mSleeping) {
9178                mSleeping = false;
9179                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9180            }
9181        }
9182    }
9183
9184    void wakingUp() {
9185        synchronized(this) {
9186            mWentToSleep = false;
9187            updateEventDispatchingLocked();
9188            comeOutOfSleepIfNeededLocked();
9189        }
9190    }
9191
9192    void startRunningVoiceLocked() {
9193        if (!mRunningVoice) {
9194            mRunningVoice = true;
9195            comeOutOfSleepIfNeededLocked();
9196        }
9197    }
9198
9199    private void updateEventDispatchingLocked() {
9200        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9201    }
9202
9203    public void setLockScreenShown(boolean shown) {
9204        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9205                != PackageManager.PERMISSION_GRANTED) {
9206            throw new SecurityException("Requires permission "
9207                    + android.Manifest.permission.DEVICE_POWER);
9208        }
9209
9210        synchronized(this) {
9211            long ident = Binder.clearCallingIdentity();
9212            try {
9213                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9214                mLockScreenShown = shown;
9215                comeOutOfSleepIfNeededLocked();
9216            } finally {
9217                Binder.restoreCallingIdentity(ident);
9218            }
9219        }
9220    }
9221
9222    @Override
9223    public void stopAppSwitches() {
9224        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9225                != PackageManager.PERMISSION_GRANTED) {
9226            throw new SecurityException("Requires permission "
9227                    + android.Manifest.permission.STOP_APP_SWITCHES);
9228        }
9229
9230        synchronized(this) {
9231            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9232                    + APP_SWITCH_DELAY_TIME;
9233            mDidAppSwitch = false;
9234            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9235            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9236            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9237        }
9238    }
9239
9240    public void resumeAppSwitches() {
9241        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9242                != PackageManager.PERMISSION_GRANTED) {
9243            throw new SecurityException("Requires permission "
9244                    + android.Manifest.permission.STOP_APP_SWITCHES);
9245        }
9246
9247        synchronized(this) {
9248            // Note that we don't execute any pending app switches... we will
9249            // let those wait until either the timeout, or the next start
9250            // activity request.
9251            mAppSwitchesAllowedTime = 0;
9252        }
9253    }
9254
9255    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9256            String name) {
9257        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9258            return true;
9259        }
9260
9261        final int perm = checkComponentPermission(
9262                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9263                callingUid, -1, true);
9264        if (perm == PackageManager.PERMISSION_GRANTED) {
9265            return true;
9266        }
9267
9268        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9269        return false;
9270    }
9271
9272    public void setDebugApp(String packageName, boolean waitForDebugger,
9273            boolean persistent) {
9274        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9275                "setDebugApp()");
9276
9277        long ident = Binder.clearCallingIdentity();
9278        try {
9279            // Note that this is not really thread safe if there are multiple
9280            // callers into it at the same time, but that's not a situation we
9281            // care about.
9282            if (persistent) {
9283                final ContentResolver resolver = mContext.getContentResolver();
9284                Settings.Global.putString(
9285                    resolver, Settings.Global.DEBUG_APP,
9286                    packageName);
9287                Settings.Global.putInt(
9288                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9289                    waitForDebugger ? 1 : 0);
9290            }
9291
9292            synchronized (this) {
9293                if (!persistent) {
9294                    mOrigDebugApp = mDebugApp;
9295                    mOrigWaitForDebugger = mWaitForDebugger;
9296                }
9297                mDebugApp = packageName;
9298                mWaitForDebugger = waitForDebugger;
9299                mDebugTransient = !persistent;
9300                if (packageName != null) {
9301                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9302                            false, UserHandle.USER_ALL, "set debug app");
9303                }
9304            }
9305        } finally {
9306            Binder.restoreCallingIdentity(ident);
9307        }
9308    }
9309
9310    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9311        synchronized (this) {
9312            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9313            if (!isDebuggable) {
9314                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9315                    throw new SecurityException("Process not debuggable: " + app.packageName);
9316                }
9317            }
9318
9319            mOpenGlTraceApp = processName;
9320        }
9321    }
9322
9323    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9324            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9325        synchronized (this) {
9326            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9327            if (!isDebuggable) {
9328                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9329                    throw new SecurityException("Process not debuggable: " + app.packageName);
9330                }
9331            }
9332            mProfileApp = processName;
9333            mProfileFile = profileFile;
9334            if (mProfileFd != null) {
9335                try {
9336                    mProfileFd.close();
9337                } catch (IOException e) {
9338                }
9339                mProfileFd = null;
9340            }
9341            mProfileFd = profileFd;
9342            mProfileType = 0;
9343            mAutoStopProfiler = autoStopProfiler;
9344        }
9345    }
9346
9347    @Override
9348    public void setAlwaysFinish(boolean enabled) {
9349        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9350                "setAlwaysFinish()");
9351
9352        Settings.Global.putInt(
9353                mContext.getContentResolver(),
9354                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9355
9356        synchronized (this) {
9357            mAlwaysFinishActivities = enabled;
9358        }
9359    }
9360
9361    @Override
9362    public void setActivityController(IActivityController controller) {
9363        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9364                "setActivityController()");
9365        synchronized (this) {
9366            mController = controller;
9367            Watchdog.getInstance().setActivityController(controller);
9368        }
9369    }
9370
9371    @Override
9372    public void setUserIsMonkey(boolean userIsMonkey) {
9373        synchronized (this) {
9374            synchronized (mPidsSelfLocked) {
9375                final int callingPid = Binder.getCallingPid();
9376                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9377                if (precessRecord == null) {
9378                    throw new SecurityException("Unknown process: " + callingPid);
9379                }
9380                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9381                    throw new SecurityException("Only an instrumentation process "
9382                            + "with a UiAutomation can call setUserIsMonkey");
9383                }
9384            }
9385            mUserIsMonkey = userIsMonkey;
9386        }
9387    }
9388
9389    @Override
9390    public boolean isUserAMonkey() {
9391        synchronized (this) {
9392            // If there is a controller also implies the user is a monkey.
9393            return (mUserIsMonkey || mController != null);
9394        }
9395    }
9396
9397    public void requestBugReport() {
9398        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9399        SystemProperties.set("ctl.start", "bugreport");
9400    }
9401
9402    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9403        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9404    }
9405
9406    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9407        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9408            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9409        }
9410        return KEY_DISPATCHING_TIMEOUT;
9411    }
9412
9413    @Override
9414    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9415        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9416                != PackageManager.PERMISSION_GRANTED) {
9417            throw new SecurityException("Requires permission "
9418                    + android.Manifest.permission.FILTER_EVENTS);
9419        }
9420        ProcessRecord proc;
9421        long timeout;
9422        synchronized (this) {
9423            synchronized (mPidsSelfLocked) {
9424                proc = mPidsSelfLocked.get(pid);
9425            }
9426            timeout = getInputDispatchingTimeoutLocked(proc);
9427        }
9428
9429        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9430            return -1;
9431        }
9432
9433        return timeout;
9434    }
9435
9436    /**
9437     * Handle input dispatching timeouts.
9438     * Returns whether input dispatching should be aborted or not.
9439     */
9440    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9441            final ActivityRecord activity, final ActivityRecord parent,
9442            final boolean aboveSystem, String reason) {
9443        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9444                != PackageManager.PERMISSION_GRANTED) {
9445            throw new SecurityException("Requires permission "
9446                    + android.Manifest.permission.FILTER_EVENTS);
9447        }
9448
9449        final String annotation;
9450        if (reason == null) {
9451            annotation = "Input dispatching timed out";
9452        } else {
9453            annotation = "Input dispatching timed out (" + reason + ")";
9454        }
9455
9456        if (proc != null) {
9457            synchronized (this) {
9458                if (proc.debugging) {
9459                    return false;
9460                }
9461
9462                if (mDidDexOpt) {
9463                    // Give more time since we were dexopting.
9464                    mDidDexOpt = false;
9465                    return false;
9466                }
9467
9468                if (proc.instrumentationClass != null) {
9469                    Bundle info = new Bundle();
9470                    info.putString("shortMsg", "keyDispatchingTimedOut");
9471                    info.putString("longMsg", annotation);
9472                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9473                    return true;
9474                }
9475            }
9476            mHandler.post(new Runnable() {
9477                @Override
9478                public void run() {
9479                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9480                }
9481            });
9482        }
9483
9484        return true;
9485    }
9486
9487    public Bundle getAssistContextExtras(int requestType) {
9488        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9489                "getAssistContextExtras()");
9490        PendingAssistExtras pae;
9491        Bundle extras = new Bundle();
9492        synchronized (this) {
9493            ActivityRecord activity = getFocusedStack().mResumedActivity;
9494            if (activity == null) {
9495                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9496                return null;
9497            }
9498            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9499            if (activity.app == null || activity.app.thread == null) {
9500                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9501                return extras;
9502            }
9503            if (activity.app.pid == Binder.getCallingPid()) {
9504                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9505                return extras;
9506            }
9507            pae = new PendingAssistExtras(activity);
9508            try {
9509                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9510                        requestType);
9511                mPendingAssistExtras.add(pae);
9512                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9513            } catch (RemoteException e) {
9514                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9515                return extras;
9516            }
9517        }
9518        synchronized (pae) {
9519            while (!pae.haveResult) {
9520                try {
9521                    pae.wait();
9522                } catch (InterruptedException e) {
9523                }
9524            }
9525            if (pae.result != null) {
9526                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9527            }
9528        }
9529        synchronized (this) {
9530            mPendingAssistExtras.remove(pae);
9531            mHandler.removeCallbacks(pae);
9532        }
9533        return extras;
9534    }
9535
9536    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9537        PendingAssistExtras pae = (PendingAssistExtras)token;
9538        synchronized (pae) {
9539            pae.result = extras;
9540            pae.haveResult = true;
9541            pae.notifyAll();
9542        }
9543    }
9544
9545    public void registerProcessObserver(IProcessObserver observer) {
9546        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9547                "registerProcessObserver()");
9548        synchronized (this) {
9549            mProcessObservers.register(observer);
9550        }
9551    }
9552
9553    @Override
9554    public void unregisterProcessObserver(IProcessObserver observer) {
9555        synchronized (this) {
9556            mProcessObservers.unregister(observer);
9557        }
9558    }
9559
9560    @Override
9561    public boolean convertFromTranslucent(IBinder token) {
9562        final long origId = Binder.clearCallingIdentity();
9563        try {
9564            synchronized (this) {
9565                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9566                if (r == null) {
9567                    return false;
9568                }
9569                if (r.changeWindowTranslucency(true)) {
9570                    mWindowManager.setAppFullscreen(token, true);
9571                    r.task.stack.releaseMediaResources();
9572                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9573                    return true;
9574                }
9575                return false;
9576            }
9577        } finally {
9578            Binder.restoreCallingIdentity(origId);
9579        }
9580    }
9581
9582    @Override
9583    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9584        final long origId = Binder.clearCallingIdentity();
9585        try {
9586            synchronized (this) {
9587                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9588                if (r == null) {
9589                    return false;
9590                }
9591                int index = r.task.mActivities.lastIndexOf(r);
9592                if (index > 0) {
9593                    ActivityRecord under = r.task.mActivities.get(index - 1);
9594                    under.returningOptions = options;
9595                }
9596                if (r.changeWindowTranslucency(false)) {
9597                    r.task.stack.convertToTranslucent(r);
9598                    mWindowManager.setAppFullscreen(token, false);
9599                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9600                    return true;
9601                } else {
9602                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9603                    return false;
9604                }
9605            }
9606        } finally {
9607            Binder.restoreCallingIdentity(origId);
9608        }
9609    }
9610
9611    @Override
9612    public boolean setMediaPlaying(IBinder token, boolean playing) {
9613        final long origId = Binder.clearCallingIdentity();
9614        try {
9615            synchronized (this) {
9616                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9617                if (r != null) {
9618                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9619                }
9620            }
9621            return false;
9622        } finally {
9623            Binder.restoreCallingIdentity(origId);
9624        }
9625    }
9626
9627    @Override
9628    public boolean isBackgroundMediaPlaying(IBinder token) {
9629        final long origId = Binder.clearCallingIdentity();
9630        try {
9631            synchronized (this) {
9632                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9633                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9634                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9635                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9636                return playing;
9637            }
9638        } finally {
9639            Binder.restoreCallingIdentity(origId);
9640        }
9641    }
9642
9643    @Override
9644    public ActivityOptions getActivityOptions(IBinder token) {
9645        final long origId = Binder.clearCallingIdentity();
9646        try {
9647            synchronized (this) {
9648                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9649                if (r != null) {
9650                    final ActivityOptions activityOptions = r.pendingOptions;
9651                    r.pendingOptions = null;
9652                    return activityOptions;
9653                }
9654                return null;
9655            }
9656        } finally {
9657            Binder.restoreCallingIdentity(origId);
9658        }
9659    }
9660
9661    @Override
9662    public void setImmersive(IBinder token, boolean immersive) {
9663        synchronized(this) {
9664            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9665            if (r == null) {
9666                throw new IllegalArgumentException();
9667            }
9668            r.immersive = immersive;
9669
9670            // update associated state if we're frontmost
9671            if (r == mFocusedActivity) {
9672                if (DEBUG_IMMERSIVE) {
9673                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9674                }
9675                applyUpdateLockStateLocked(r);
9676            }
9677        }
9678    }
9679
9680    @Override
9681    public boolean isImmersive(IBinder token) {
9682        synchronized (this) {
9683            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9684            if (r == null) {
9685                throw new IllegalArgumentException();
9686            }
9687            return r.immersive;
9688        }
9689    }
9690
9691    public boolean isTopActivityImmersive() {
9692        enforceNotIsolatedCaller("startActivity");
9693        synchronized (this) {
9694            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9695            return (r != null) ? r.immersive : false;
9696        }
9697    }
9698
9699    @Override
9700    public boolean isTopOfTask(IBinder token) {
9701        synchronized (this) {
9702            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9703            if (r == null) {
9704                throw new IllegalArgumentException();
9705            }
9706            return r.task.getTopActivity() == r;
9707        }
9708    }
9709
9710    public final void enterSafeMode() {
9711        synchronized(this) {
9712            // It only makes sense to do this before the system is ready
9713            // and started launching other packages.
9714            if (!mSystemReady) {
9715                try {
9716                    AppGlobals.getPackageManager().enterSafeMode();
9717                } catch (RemoteException e) {
9718                }
9719            }
9720
9721            mSafeMode = true;
9722        }
9723    }
9724
9725    public final void showSafeModeOverlay() {
9726        View v = LayoutInflater.from(mContext).inflate(
9727                com.android.internal.R.layout.safe_mode, null);
9728        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9729        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9730        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9731        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9732        lp.gravity = Gravity.BOTTOM | Gravity.START;
9733        lp.format = v.getBackground().getOpacity();
9734        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9735                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9736        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9737        ((WindowManager)mContext.getSystemService(
9738                Context.WINDOW_SERVICE)).addView(v, lp);
9739    }
9740
9741    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9742        if (!(sender instanceof PendingIntentRecord)) {
9743            return;
9744        }
9745        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9746        synchronized (stats) {
9747            if (mBatteryStatsService.isOnBattery()) {
9748                mBatteryStatsService.enforceCallingPermission();
9749                PendingIntentRecord rec = (PendingIntentRecord)sender;
9750                int MY_UID = Binder.getCallingUid();
9751                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9752                BatteryStatsImpl.Uid.Pkg pkg =
9753                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9754                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9755                pkg.incWakeupsLocked();
9756            }
9757        }
9758    }
9759
9760    public boolean killPids(int[] pids, String pReason, boolean secure) {
9761        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9762            throw new SecurityException("killPids only available to the system");
9763        }
9764        String reason = (pReason == null) ? "Unknown" : pReason;
9765        // XXX Note: don't acquire main activity lock here, because the window
9766        // manager calls in with its locks held.
9767
9768        boolean killed = false;
9769        synchronized (mPidsSelfLocked) {
9770            int[] types = new int[pids.length];
9771            int worstType = 0;
9772            for (int i=0; i<pids.length; i++) {
9773                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9774                if (proc != null) {
9775                    int type = proc.setAdj;
9776                    types[i] = type;
9777                    if (type > worstType) {
9778                        worstType = type;
9779                    }
9780                }
9781            }
9782
9783            // If the worst oom_adj is somewhere in the cached proc LRU range,
9784            // then constrain it so we will kill all cached procs.
9785            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9786                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9787                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9788            }
9789
9790            // If this is not a secure call, don't let it kill processes that
9791            // are important.
9792            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9793                worstType = ProcessList.SERVICE_ADJ;
9794            }
9795
9796            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9797            for (int i=0; i<pids.length; i++) {
9798                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9799                if (proc == null) {
9800                    continue;
9801                }
9802                int adj = proc.setAdj;
9803                if (adj >= worstType && !proc.killedByAm) {
9804                    killUnneededProcessLocked(proc, reason);
9805                    killed = true;
9806                }
9807            }
9808        }
9809        return killed;
9810    }
9811
9812    @Override
9813    public void killUid(int uid, String reason) {
9814        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9815            throw new SecurityException("killUid only available to the system");
9816        }
9817        synchronized (this) {
9818            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9819                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9820                    reason != null ? reason : "kill uid");
9821        }
9822    }
9823
9824    @Override
9825    public boolean killProcessesBelowForeground(String reason) {
9826        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9827            throw new SecurityException("killProcessesBelowForeground() only available to system");
9828        }
9829
9830        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9831    }
9832
9833    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9834        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9835            throw new SecurityException("killProcessesBelowAdj() only available to system");
9836        }
9837
9838        boolean killed = false;
9839        synchronized (mPidsSelfLocked) {
9840            final int size = mPidsSelfLocked.size();
9841            for (int i = 0; i < size; i++) {
9842                final int pid = mPidsSelfLocked.keyAt(i);
9843                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9844                if (proc == null) continue;
9845
9846                final int adj = proc.setAdj;
9847                if (adj > belowAdj && !proc.killedByAm) {
9848                    killUnneededProcessLocked(proc, reason);
9849                    killed = true;
9850                }
9851            }
9852        }
9853        return killed;
9854    }
9855
9856    @Override
9857    public void hang(final IBinder who, boolean allowRestart) {
9858        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9859                != PackageManager.PERMISSION_GRANTED) {
9860            throw new SecurityException("Requires permission "
9861                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9862        }
9863
9864        final IBinder.DeathRecipient death = new DeathRecipient() {
9865            @Override
9866            public void binderDied() {
9867                synchronized (this) {
9868                    notifyAll();
9869                }
9870            }
9871        };
9872
9873        try {
9874            who.linkToDeath(death, 0);
9875        } catch (RemoteException e) {
9876            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9877            return;
9878        }
9879
9880        synchronized (this) {
9881            Watchdog.getInstance().setAllowRestart(allowRestart);
9882            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9883            synchronized (death) {
9884                while (who.isBinderAlive()) {
9885                    try {
9886                        death.wait();
9887                    } catch (InterruptedException e) {
9888                    }
9889                }
9890            }
9891            Watchdog.getInstance().setAllowRestart(true);
9892        }
9893    }
9894
9895    @Override
9896    public void restart() {
9897        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9898                != PackageManager.PERMISSION_GRANTED) {
9899            throw new SecurityException("Requires permission "
9900                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9901        }
9902
9903        Log.i(TAG, "Sending shutdown broadcast...");
9904
9905        BroadcastReceiver br = new BroadcastReceiver() {
9906            @Override public void onReceive(Context context, Intent intent) {
9907                // Now the broadcast is done, finish up the low-level shutdown.
9908                Log.i(TAG, "Shutting down activity manager...");
9909                shutdown(10000);
9910                Log.i(TAG, "Shutdown complete, restarting!");
9911                Process.killProcess(Process.myPid());
9912                System.exit(10);
9913            }
9914        };
9915
9916        // First send the high-level shut down broadcast.
9917        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9918        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9919        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9920        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9921        mContext.sendOrderedBroadcastAsUser(intent,
9922                UserHandle.ALL, null, br, mHandler, 0, null, null);
9923        */
9924        br.onReceive(mContext, intent);
9925    }
9926
9927    private long getLowRamTimeSinceIdle(long now) {
9928        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9929    }
9930
9931    @Override
9932    public void performIdleMaintenance() {
9933        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9934                != PackageManager.PERMISSION_GRANTED) {
9935            throw new SecurityException("Requires permission "
9936                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9937        }
9938
9939        synchronized (this) {
9940            final long now = SystemClock.uptimeMillis();
9941            final long timeSinceLastIdle = now - mLastIdleTime;
9942            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9943            mLastIdleTime = now;
9944            mLowRamTimeSinceLastIdle = 0;
9945            if (mLowRamStartTime != 0) {
9946                mLowRamStartTime = now;
9947            }
9948
9949            StringBuilder sb = new StringBuilder(128);
9950            sb.append("Idle maintenance over ");
9951            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9952            sb.append(" low RAM for ");
9953            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9954            Slog.i(TAG, sb.toString());
9955
9956            // If at least 1/3 of our time since the last idle period has been spent
9957            // with RAM low, then we want to kill processes.
9958            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9959
9960            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9961                ProcessRecord proc = mLruProcesses.get(i);
9962                if (proc.notCachedSinceIdle) {
9963                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9964                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9965                        if (doKilling && proc.initialIdlePss != 0
9966                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9967                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9968                                    + " from " + proc.initialIdlePss + ")");
9969                        }
9970                    }
9971                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9972                    proc.notCachedSinceIdle = true;
9973                    proc.initialIdlePss = 0;
9974                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9975                            isSleeping(), now);
9976                }
9977            }
9978
9979            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9980            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9981        }
9982    }
9983
9984    private void retrieveSettings() {
9985        final ContentResolver resolver = mContext.getContentResolver();
9986        String debugApp = Settings.Global.getString(
9987            resolver, Settings.Global.DEBUG_APP);
9988        boolean waitForDebugger = Settings.Global.getInt(
9989            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9990        boolean alwaysFinishActivities = Settings.Global.getInt(
9991            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9992        boolean forceRtl = Settings.Global.getInt(
9993                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9994        // Transfer any global setting for forcing RTL layout, into a System Property
9995        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9996
9997        Configuration configuration = new Configuration();
9998        Settings.System.getConfiguration(resolver, configuration);
9999        if (forceRtl) {
10000            // This will take care of setting the correct layout direction flags
10001            configuration.setLayoutDirection(configuration.locale);
10002        }
10003
10004        synchronized (this) {
10005            mDebugApp = mOrigDebugApp = debugApp;
10006            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10007            mAlwaysFinishActivities = alwaysFinishActivities;
10008            // This happens before any activities are started, so we can
10009            // change mConfiguration in-place.
10010            updateConfigurationLocked(configuration, null, false, true);
10011            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10012        }
10013    }
10014
10015    public boolean testIsSystemReady() {
10016        // no need to synchronize(this) just to read & return the value
10017        return mSystemReady;
10018    }
10019
10020    private static File getCalledPreBootReceiversFile() {
10021        File dataDir = Environment.getDataDirectory();
10022        File systemDir = new File(dataDir, "system");
10023        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10024        return fname;
10025    }
10026
10027    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10028        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10029        File file = getCalledPreBootReceiversFile();
10030        FileInputStream fis = null;
10031        try {
10032            fis = new FileInputStream(file);
10033            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10034            int fvers = dis.readInt();
10035            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10036                String vers = dis.readUTF();
10037                String codename = dis.readUTF();
10038                String build = dis.readUTF();
10039                if (android.os.Build.VERSION.RELEASE.equals(vers)
10040                        && android.os.Build.VERSION.CODENAME.equals(codename)
10041                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10042                    int num = dis.readInt();
10043                    while (num > 0) {
10044                        num--;
10045                        String pkg = dis.readUTF();
10046                        String cls = dis.readUTF();
10047                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10048                    }
10049                }
10050            }
10051        } catch (FileNotFoundException e) {
10052        } catch (IOException e) {
10053            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10054        } finally {
10055            if (fis != null) {
10056                try {
10057                    fis.close();
10058                } catch (IOException e) {
10059                }
10060            }
10061        }
10062        return lastDoneReceivers;
10063    }
10064
10065    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10066        File file = getCalledPreBootReceiversFile();
10067        FileOutputStream fos = null;
10068        DataOutputStream dos = null;
10069        try {
10070            fos = new FileOutputStream(file);
10071            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10072            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10073            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10074            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10075            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10076            dos.writeInt(list.size());
10077            for (int i=0; i<list.size(); i++) {
10078                dos.writeUTF(list.get(i).getPackageName());
10079                dos.writeUTF(list.get(i).getClassName());
10080            }
10081        } catch (IOException e) {
10082            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10083            file.delete();
10084        } finally {
10085            FileUtils.sync(fos);
10086            if (dos != null) {
10087                try {
10088                    dos.close();
10089                } catch (IOException e) {
10090                    // TODO Auto-generated catch block
10091                    e.printStackTrace();
10092                }
10093            }
10094        }
10095    }
10096
10097    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10098            ArrayList<ComponentName> doneReceivers, int userId) {
10099        boolean waitingUpdate = false;
10100        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10101        List<ResolveInfo> ris = null;
10102        try {
10103            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10104                    intent, null, 0, userId);
10105        } catch (RemoteException e) {
10106        }
10107        if (ris != null) {
10108            for (int i=ris.size()-1; i>=0; i--) {
10109                if ((ris.get(i).activityInfo.applicationInfo.flags
10110                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10111                    ris.remove(i);
10112                }
10113            }
10114            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10115
10116            // For User 0, load the version number. When delivering to a new user, deliver
10117            // to all receivers.
10118            if (userId == UserHandle.USER_OWNER) {
10119                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10120                for (int i=0; i<ris.size(); i++) {
10121                    ActivityInfo ai = ris.get(i).activityInfo;
10122                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10123                    if (lastDoneReceivers.contains(comp)) {
10124                        // We already did the pre boot receiver for this app with the current
10125                        // platform version, so don't do it again...
10126                        ris.remove(i);
10127                        i--;
10128                        // ...however, do keep it as one that has been done, so we don't
10129                        // forget about it when rewriting the file of last done receivers.
10130                        doneReceivers.add(comp);
10131                    }
10132                }
10133            }
10134
10135            // If primary user, send broadcast to all available users, else just to userId
10136            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10137                    : new int[] { userId };
10138            for (int i = 0; i < ris.size(); i++) {
10139                ActivityInfo ai = ris.get(i).activityInfo;
10140                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10141                doneReceivers.add(comp);
10142                intent.setComponent(comp);
10143                for (int j=0; j<users.length; j++) {
10144                    IIntentReceiver finisher = null;
10145                    // On last receiver and user, set up a completion callback
10146                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10147                        finisher = new IIntentReceiver.Stub() {
10148                            public void performReceive(Intent intent, int resultCode,
10149                                    String data, Bundle extras, boolean ordered,
10150                                    boolean sticky, int sendingUser) {
10151                                // The raw IIntentReceiver interface is called
10152                                // with the AM lock held, so redispatch to
10153                                // execute our code without the lock.
10154                                mHandler.post(onFinishCallback);
10155                            }
10156                        };
10157                    }
10158                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10159                            + " for user " + users[j]);
10160                    broadcastIntentLocked(null, null, intent, null, finisher,
10161                            0, null, null, null, AppOpsManager.OP_NONE,
10162                            true, false, MY_PID, Process.SYSTEM_UID,
10163                            users[j]);
10164                    if (finisher != null) {
10165                        waitingUpdate = true;
10166                    }
10167                }
10168            }
10169        }
10170
10171        return waitingUpdate;
10172    }
10173
10174    public void systemReady(final Runnable goingCallback) {
10175        synchronized(this) {
10176            if (mSystemReady) {
10177                // If we're done calling all the receivers, run the next "boot phase" passed in
10178                // by the SystemServer
10179                if (goingCallback != null) {
10180                    goingCallback.run();
10181                }
10182                return;
10183            }
10184
10185            // Make sure we have the current profile info, since it is needed for
10186            // security checks.
10187            updateCurrentProfileIdsLocked();
10188
10189            if (mRecentTasks == null) {
10190                mRecentTasks = mTaskPersister.restoreTasksLocked();
10191                if (!mRecentTasks.isEmpty()) {
10192                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10193                }
10194                mTaskPersister.startPersisting();
10195            }
10196
10197            // Check to see if there are any update receivers to run.
10198            if (!mDidUpdate) {
10199                if (mWaitingUpdate) {
10200                    return;
10201                }
10202                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10203                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10204                    public void run() {
10205                        synchronized (ActivityManagerService.this) {
10206                            mDidUpdate = true;
10207                        }
10208                        writeLastDonePreBootReceivers(doneReceivers);
10209                        showBootMessage(mContext.getText(
10210                                R.string.android_upgrading_complete),
10211                                false);
10212                        systemReady(goingCallback);
10213                    }
10214                }, doneReceivers, UserHandle.USER_OWNER);
10215
10216                if (mWaitingUpdate) {
10217                    return;
10218                }
10219                mDidUpdate = true;
10220            }
10221
10222            mAppOpsService.systemReady();
10223            mSystemReady = true;
10224        }
10225
10226        ArrayList<ProcessRecord> procsToKill = null;
10227        synchronized(mPidsSelfLocked) {
10228            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10229                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10230                if (!isAllowedWhileBooting(proc.info)){
10231                    if (procsToKill == null) {
10232                        procsToKill = new ArrayList<ProcessRecord>();
10233                    }
10234                    procsToKill.add(proc);
10235                }
10236            }
10237        }
10238
10239        synchronized(this) {
10240            if (procsToKill != null) {
10241                for (int i=procsToKill.size()-1; i>=0; i--) {
10242                    ProcessRecord proc = procsToKill.get(i);
10243                    Slog.i(TAG, "Removing system update proc: " + proc);
10244                    removeProcessLocked(proc, true, false, "system update done");
10245                }
10246            }
10247
10248            // Now that we have cleaned up any update processes, we
10249            // are ready to start launching real processes and know that
10250            // we won't trample on them any more.
10251            mProcessesReady = true;
10252        }
10253
10254        Slog.i(TAG, "System now ready");
10255        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10256            SystemClock.uptimeMillis());
10257
10258        synchronized(this) {
10259            // Make sure we have no pre-ready processes sitting around.
10260
10261            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10262                ResolveInfo ri = mContext.getPackageManager()
10263                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10264                                STOCK_PM_FLAGS);
10265                CharSequence errorMsg = null;
10266                if (ri != null) {
10267                    ActivityInfo ai = ri.activityInfo;
10268                    ApplicationInfo app = ai.applicationInfo;
10269                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10270                        mTopAction = Intent.ACTION_FACTORY_TEST;
10271                        mTopData = null;
10272                        mTopComponent = new ComponentName(app.packageName,
10273                                ai.name);
10274                    } else {
10275                        errorMsg = mContext.getResources().getText(
10276                                com.android.internal.R.string.factorytest_not_system);
10277                    }
10278                } else {
10279                    errorMsg = mContext.getResources().getText(
10280                            com.android.internal.R.string.factorytest_no_action);
10281                }
10282                if (errorMsg != null) {
10283                    mTopAction = null;
10284                    mTopData = null;
10285                    mTopComponent = null;
10286                    Message msg = Message.obtain();
10287                    msg.what = SHOW_FACTORY_ERROR_MSG;
10288                    msg.getData().putCharSequence("msg", errorMsg);
10289                    mHandler.sendMessage(msg);
10290                }
10291            }
10292        }
10293
10294        retrieveSettings();
10295
10296        synchronized (this) {
10297            readGrantedUriPermissionsLocked();
10298        }
10299
10300        if (goingCallback != null) goingCallback.run();
10301
10302        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10303                Integer.toString(mCurrentUserId), mCurrentUserId);
10304        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10305                Integer.toString(mCurrentUserId), mCurrentUserId);
10306        mSystemServiceManager.startUser(mCurrentUserId);
10307
10308        synchronized (this) {
10309            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10310                try {
10311                    List apps = AppGlobals.getPackageManager().
10312                        getPersistentApplications(STOCK_PM_FLAGS);
10313                    if (apps != null) {
10314                        int N = apps.size();
10315                        int i;
10316                        for (i=0; i<N; i++) {
10317                            ApplicationInfo info
10318                                = (ApplicationInfo)apps.get(i);
10319                            if (info != null &&
10320                                    !info.packageName.equals("android")) {
10321                                addAppLocked(info, false, null /* ABI override */);
10322                            }
10323                        }
10324                    }
10325                } catch (RemoteException ex) {
10326                    // pm is in same process, this will never happen.
10327                }
10328            }
10329
10330            // Start up initial activity.
10331            mBooting = true;
10332
10333            try {
10334                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10335                    Message msg = Message.obtain();
10336                    msg.what = SHOW_UID_ERROR_MSG;
10337                    mHandler.sendMessage(msg);
10338                }
10339            } catch (RemoteException e) {
10340            }
10341
10342            long ident = Binder.clearCallingIdentity();
10343            try {
10344                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10345                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10346                        | Intent.FLAG_RECEIVER_FOREGROUND);
10347                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10348                broadcastIntentLocked(null, null, intent,
10349                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10350                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10351                intent = new Intent(Intent.ACTION_USER_STARTING);
10352                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10353                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10354                broadcastIntentLocked(null, null, intent,
10355                        null, new IIntentReceiver.Stub() {
10356                            @Override
10357                            public void performReceive(Intent intent, int resultCode, String data,
10358                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10359                                    throws RemoteException {
10360                            }
10361                        }, 0, null, null,
10362                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10363                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10364            } catch (Throwable t) {
10365                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10366            } finally {
10367                Binder.restoreCallingIdentity(ident);
10368            }
10369            mStackSupervisor.resumeTopActivitiesLocked();
10370            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10371        }
10372    }
10373
10374    private boolean makeAppCrashingLocked(ProcessRecord app,
10375            String shortMsg, String longMsg, String stackTrace) {
10376        app.crashing = true;
10377        app.crashingReport = generateProcessError(app,
10378                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10379        startAppProblemLocked(app);
10380        app.stopFreezingAllLocked();
10381        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10382    }
10383
10384    private void makeAppNotRespondingLocked(ProcessRecord app,
10385            String activity, String shortMsg, String longMsg) {
10386        app.notResponding = true;
10387        app.notRespondingReport = generateProcessError(app,
10388                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10389                activity, shortMsg, longMsg, null);
10390        startAppProblemLocked(app);
10391        app.stopFreezingAllLocked();
10392    }
10393
10394    /**
10395     * Generate a process error record, suitable for attachment to a ProcessRecord.
10396     *
10397     * @param app The ProcessRecord in which the error occurred.
10398     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10399     *                      ActivityManager.AppErrorStateInfo
10400     * @param activity The activity associated with the crash, if known.
10401     * @param shortMsg Short message describing the crash.
10402     * @param longMsg Long message describing the crash.
10403     * @param stackTrace Full crash stack trace, may be null.
10404     *
10405     * @return Returns a fully-formed AppErrorStateInfo record.
10406     */
10407    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10408            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10409        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10410
10411        report.condition = condition;
10412        report.processName = app.processName;
10413        report.pid = app.pid;
10414        report.uid = app.info.uid;
10415        report.tag = activity;
10416        report.shortMsg = shortMsg;
10417        report.longMsg = longMsg;
10418        report.stackTrace = stackTrace;
10419
10420        return report;
10421    }
10422
10423    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10424        synchronized (this) {
10425            app.crashing = false;
10426            app.crashingReport = null;
10427            app.notResponding = false;
10428            app.notRespondingReport = null;
10429            if (app.anrDialog == fromDialog) {
10430                app.anrDialog = null;
10431            }
10432            if (app.waitDialog == fromDialog) {
10433                app.waitDialog = null;
10434            }
10435            if (app.pid > 0 && app.pid != MY_PID) {
10436                handleAppCrashLocked(app, null, null, null);
10437                killUnneededProcessLocked(app, "user request after error");
10438            }
10439        }
10440    }
10441
10442    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10443            String stackTrace) {
10444        long now = SystemClock.uptimeMillis();
10445
10446        Long crashTime;
10447        if (!app.isolated) {
10448            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10449        } else {
10450            crashTime = null;
10451        }
10452        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10453            // This process loses!
10454            Slog.w(TAG, "Process " + app.info.processName
10455                    + " has crashed too many times: killing!");
10456            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10457                    app.userId, app.info.processName, app.uid);
10458            mStackSupervisor.handleAppCrashLocked(app);
10459            if (!app.persistent) {
10460                // We don't want to start this process again until the user
10461                // explicitly does so...  but for persistent process, we really
10462                // need to keep it running.  If a persistent process is actually
10463                // repeatedly crashing, then badness for everyone.
10464                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10465                        app.info.processName);
10466                if (!app.isolated) {
10467                    // XXX We don't have a way to mark isolated processes
10468                    // as bad, since they don't have a peristent identity.
10469                    mBadProcesses.put(app.info.processName, app.uid,
10470                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10471                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10472                }
10473                app.bad = true;
10474                app.removed = true;
10475                // Don't let services in this process be restarted and potentially
10476                // annoy the user repeatedly.  Unless it is persistent, since those
10477                // processes run critical code.
10478                removeProcessLocked(app, false, false, "crash");
10479                mStackSupervisor.resumeTopActivitiesLocked();
10480                return false;
10481            }
10482            mStackSupervisor.resumeTopActivitiesLocked();
10483        } else {
10484            mStackSupervisor.finishTopRunningActivityLocked(app);
10485        }
10486
10487        // Bump up the crash count of any services currently running in the proc.
10488        for (int i=app.services.size()-1; i>=0; i--) {
10489            // Any services running in the application need to be placed
10490            // back in the pending list.
10491            ServiceRecord sr = app.services.valueAt(i);
10492            sr.crashCount++;
10493        }
10494
10495        // If the crashing process is what we consider to be the "home process" and it has been
10496        // replaced by a third-party app, clear the package preferred activities from packages
10497        // with a home activity running in the process to prevent a repeatedly crashing app
10498        // from blocking the user to manually clear the list.
10499        final ArrayList<ActivityRecord> activities = app.activities;
10500        if (app == mHomeProcess && activities.size() > 0
10501                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10502            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10503                final ActivityRecord r = activities.get(activityNdx);
10504                if (r.isHomeActivity()) {
10505                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10506                    try {
10507                        ActivityThread.getPackageManager()
10508                                .clearPackagePreferredActivities(r.packageName);
10509                    } catch (RemoteException c) {
10510                        // pm is in same process, this will never happen.
10511                    }
10512                }
10513            }
10514        }
10515
10516        if (!app.isolated) {
10517            // XXX Can't keep track of crash times for isolated processes,
10518            // because they don't have a perisistent identity.
10519            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10520        }
10521
10522        return true;
10523    }
10524
10525    void startAppProblemLocked(ProcessRecord app) {
10526        if (app.userId == mCurrentUserId) {
10527            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10528                    mContext, app.info.packageName, app.info.flags);
10529        } else {
10530            // If this app is not running under the current user, then we
10531            // can't give it a report button because that would require
10532            // launching the report UI under a different user.
10533            app.errorReportReceiver = null;
10534        }
10535        skipCurrentReceiverLocked(app);
10536    }
10537
10538    void skipCurrentReceiverLocked(ProcessRecord app) {
10539        for (BroadcastQueue queue : mBroadcastQueues) {
10540            queue.skipCurrentReceiverLocked(app);
10541        }
10542    }
10543
10544    /**
10545     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10546     * The application process will exit immediately after this call returns.
10547     * @param app object of the crashing app, null for the system server
10548     * @param crashInfo describing the exception
10549     */
10550    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10551        ProcessRecord r = findAppProcess(app, "Crash");
10552        final String processName = app == null ? "system_server"
10553                : (r == null ? "unknown" : r.processName);
10554
10555        handleApplicationCrashInner("crash", r, processName, crashInfo);
10556    }
10557
10558    /* Native crash reporting uses this inner version because it needs to be somewhat
10559     * decoupled from the AM-managed cleanup lifecycle
10560     */
10561    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10562            ApplicationErrorReport.CrashInfo crashInfo) {
10563        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10564                UserHandle.getUserId(Binder.getCallingUid()), processName,
10565                r == null ? -1 : r.info.flags,
10566                crashInfo.exceptionClassName,
10567                crashInfo.exceptionMessage,
10568                crashInfo.throwFileName,
10569                crashInfo.throwLineNumber);
10570
10571        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10572
10573        crashApplication(r, crashInfo);
10574    }
10575
10576    public void handleApplicationStrictModeViolation(
10577            IBinder app,
10578            int violationMask,
10579            StrictMode.ViolationInfo info) {
10580        ProcessRecord r = findAppProcess(app, "StrictMode");
10581        if (r == null) {
10582            return;
10583        }
10584
10585        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10586            Integer stackFingerprint = info.hashCode();
10587            boolean logIt = true;
10588            synchronized (mAlreadyLoggedViolatedStacks) {
10589                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10590                    logIt = false;
10591                    // TODO: sub-sample into EventLog for these, with
10592                    // the info.durationMillis?  Then we'd get
10593                    // the relative pain numbers, without logging all
10594                    // the stack traces repeatedly.  We'd want to do
10595                    // likewise in the client code, which also does
10596                    // dup suppression, before the Binder call.
10597                } else {
10598                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10599                        mAlreadyLoggedViolatedStacks.clear();
10600                    }
10601                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10602                }
10603            }
10604            if (logIt) {
10605                logStrictModeViolationToDropBox(r, info);
10606            }
10607        }
10608
10609        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10610            AppErrorResult result = new AppErrorResult();
10611            synchronized (this) {
10612                final long origId = Binder.clearCallingIdentity();
10613
10614                Message msg = Message.obtain();
10615                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10616                HashMap<String, Object> data = new HashMap<String, Object>();
10617                data.put("result", result);
10618                data.put("app", r);
10619                data.put("violationMask", violationMask);
10620                data.put("info", info);
10621                msg.obj = data;
10622                mHandler.sendMessage(msg);
10623
10624                Binder.restoreCallingIdentity(origId);
10625            }
10626            int res = result.get();
10627            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10628        }
10629    }
10630
10631    // Depending on the policy in effect, there could be a bunch of
10632    // these in quick succession so we try to batch these together to
10633    // minimize disk writes, number of dropbox entries, and maximize
10634    // compression, by having more fewer, larger records.
10635    private void logStrictModeViolationToDropBox(
10636            ProcessRecord process,
10637            StrictMode.ViolationInfo info) {
10638        if (info == null) {
10639            return;
10640        }
10641        final boolean isSystemApp = process == null ||
10642                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10643                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10644        final String processName = process == null ? "unknown" : process.processName;
10645        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10646        final DropBoxManager dbox = (DropBoxManager)
10647                mContext.getSystemService(Context.DROPBOX_SERVICE);
10648
10649        // Exit early if the dropbox isn't configured to accept this report type.
10650        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10651
10652        boolean bufferWasEmpty;
10653        boolean needsFlush;
10654        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10655        synchronized (sb) {
10656            bufferWasEmpty = sb.length() == 0;
10657            appendDropBoxProcessHeaders(process, processName, sb);
10658            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10659            sb.append("System-App: ").append(isSystemApp).append("\n");
10660            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10661            if (info.violationNumThisLoop != 0) {
10662                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10663            }
10664            if (info.numAnimationsRunning != 0) {
10665                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10666            }
10667            if (info.broadcastIntentAction != null) {
10668                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10669            }
10670            if (info.durationMillis != -1) {
10671                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10672            }
10673            if (info.numInstances != -1) {
10674                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10675            }
10676            if (info.tags != null) {
10677                for (String tag : info.tags) {
10678                    sb.append("Span-Tag: ").append(tag).append("\n");
10679                }
10680            }
10681            sb.append("\n");
10682            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10683                sb.append(info.crashInfo.stackTrace);
10684            }
10685            sb.append("\n");
10686
10687            // Only buffer up to ~64k.  Various logging bits truncate
10688            // things at 128k.
10689            needsFlush = (sb.length() > 64 * 1024);
10690        }
10691
10692        // Flush immediately if the buffer's grown too large, or this
10693        // is a non-system app.  Non-system apps are isolated with a
10694        // different tag & policy and not batched.
10695        //
10696        // Batching is useful during internal testing with
10697        // StrictMode settings turned up high.  Without batching,
10698        // thousands of separate files could be created on boot.
10699        if (!isSystemApp || needsFlush) {
10700            new Thread("Error dump: " + dropboxTag) {
10701                @Override
10702                public void run() {
10703                    String report;
10704                    synchronized (sb) {
10705                        report = sb.toString();
10706                        sb.delete(0, sb.length());
10707                        sb.trimToSize();
10708                    }
10709                    if (report.length() != 0) {
10710                        dbox.addText(dropboxTag, report);
10711                    }
10712                }
10713            }.start();
10714            return;
10715        }
10716
10717        // System app batching:
10718        if (!bufferWasEmpty) {
10719            // An existing dropbox-writing thread is outstanding, so
10720            // we don't need to start it up.  The existing thread will
10721            // catch the buffer appends we just did.
10722            return;
10723        }
10724
10725        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10726        // (After this point, we shouldn't access AMS internal data structures.)
10727        new Thread("Error dump: " + dropboxTag) {
10728            @Override
10729            public void run() {
10730                // 5 second sleep to let stacks arrive and be batched together
10731                try {
10732                    Thread.sleep(5000);  // 5 seconds
10733                } catch (InterruptedException e) {}
10734
10735                String errorReport;
10736                synchronized (mStrictModeBuffer) {
10737                    errorReport = mStrictModeBuffer.toString();
10738                    if (errorReport.length() == 0) {
10739                        return;
10740                    }
10741                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10742                    mStrictModeBuffer.trimToSize();
10743                }
10744                dbox.addText(dropboxTag, errorReport);
10745            }
10746        }.start();
10747    }
10748
10749    /**
10750     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10751     * @param app object of the crashing app, null for the system server
10752     * @param tag reported by the caller
10753     * @param crashInfo describing the context of the error
10754     * @return true if the process should exit immediately (WTF is fatal)
10755     */
10756    public boolean handleApplicationWtf(IBinder app, String tag,
10757            ApplicationErrorReport.CrashInfo crashInfo) {
10758        ProcessRecord r = findAppProcess(app, "WTF");
10759        final String processName = app == null ? "system_server"
10760                : (r == null ? "unknown" : r.processName);
10761
10762        EventLog.writeEvent(EventLogTags.AM_WTF,
10763                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10764                processName,
10765                r == null ? -1 : r.info.flags,
10766                tag, crashInfo.exceptionMessage);
10767
10768        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10769
10770        if (r != null && r.pid != Process.myPid() &&
10771                Settings.Global.getInt(mContext.getContentResolver(),
10772                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10773            crashApplication(r, crashInfo);
10774            return true;
10775        } else {
10776            return false;
10777        }
10778    }
10779
10780    /**
10781     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10782     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10783     */
10784    private ProcessRecord findAppProcess(IBinder app, String reason) {
10785        if (app == null) {
10786            return null;
10787        }
10788
10789        synchronized (this) {
10790            final int NP = mProcessNames.getMap().size();
10791            for (int ip=0; ip<NP; ip++) {
10792                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10793                final int NA = apps.size();
10794                for (int ia=0; ia<NA; ia++) {
10795                    ProcessRecord p = apps.valueAt(ia);
10796                    if (p.thread != null && p.thread.asBinder() == app) {
10797                        return p;
10798                    }
10799                }
10800            }
10801
10802            Slog.w(TAG, "Can't find mystery application for " + reason
10803                    + " from pid=" + Binder.getCallingPid()
10804                    + " uid=" + Binder.getCallingUid() + ": " + app);
10805            return null;
10806        }
10807    }
10808
10809    /**
10810     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10811     * to append various headers to the dropbox log text.
10812     */
10813    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10814            StringBuilder sb) {
10815        // Watchdog thread ends up invoking this function (with
10816        // a null ProcessRecord) to add the stack file to dropbox.
10817        // Do not acquire a lock on this (am) in such cases, as it
10818        // could cause a potential deadlock, if and when watchdog
10819        // is invoked due to unavailability of lock on am and it
10820        // would prevent watchdog from killing system_server.
10821        if (process == null) {
10822            sb.append("Process: ").append(processName).append("\n");
10823            return;
10824        }
10825        // Note: ProcessRecord 'process' is guarded by the service
10826        // instance.  (notably process.pkgList, which could otherwise change
10827        // concurrently during execution of this method)
10828        synchronized (this) {
10829            sb.append("Process: ").append(processName).append("\n");
10830            int flags = process.info.flags;
10831            IPackageManager pm = AppGlobals.getPackageManager();
10832            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10833            for (int ip=0; ip<process.pkgList.size(); ip++) {
10834                String pkg = process.pkgList.keyAt(ip);
10835                sb.append("Package: ").append(pkg);
10836                try {
10837                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10838                    if (pi != null) {
10839                        sb.append(" v").append(pi.versionCode);
10840                        if (pi.versionName != null) {
10841                            sb.append(" (").append(pi.versionName).append(")");
10842                        }
10843                    }
10844                } catch (RemoteException e) {
10845                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10846                }
10847                sb.append("\n");
10848            }
10849        }
10850    }
10851
10852    private static String processClass(ProcessRecord process) {
10853        if (process == null || process.pid == MY_PID) {
10854            return "system_server";
10855        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10856            return "system_app";
10857        } else {
10858            return "data_app";
10859        }
10860    }
10861
10862    /**
10863     * Write a description of an error (crash, WTF, ANR) to the drop box.
10864     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10865     * @param process which caused the error, null means the system server
10866     * @param activity which triggered the error, null if unknown
10867     * @param parent activity related to the error, null if unknown
10868     * @param subject line related to the error, null if absent
10869     * @param report in long form describing the error, null if absent
10870     * @param logFile to include in the report, null if none
10871     * @param crashInfo giving an application stack trace, null if absent
10872     */
10873    public void addErrorToDropBox(String eventType,
10874            ProcessRecord process, String processName, ActivityRecord activity,
10875            ActivityRecord parent, String subject,
10876            final String report, final File logFile,
10877            final ApplicationErrorReport.CrashInfo crashInfo) {
10878        // NOTE -- this must never acquire the ActivityManagerService lock,
10879        // otherwise the watchdog may be prevented from resetting the system.
10880
10881        final String dropboxTag = processClass(process) + "_" + eventType;
10882        final DropBoxManager dbox = (DropBoxManager)
10883                mContext.getSystemService(Context.DROPBOX_SERVICE);
10884
10885        // Exit early if the dropbox isn't configured to accept this report type.
10886        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10887
10888        final StringBuilder sb = new StringBuilder(1024);
10889        appendDropBoxProcessHeaders(process, processName, sb);
10890        if (activity != null) {
10891            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10892        }
10893        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10894            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10895        }
10896        if (parent != null && parent != activity) {
10897            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10898        }
10899        if (subject != null) {
10900            sb.append("Subject: ").append(subject).append("\n");
10901        }
10902        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10903        if (Debug.isDebuggerConnected()) {
10904            sb.append("Debugger: Connected\n");
10905        }
10906        sb.append("\n");
10907
10908        // Do the rest in a worker thread to avoid blocking the caller on I/O
10909        // (After this point, we shouldn't access AMS internal data structures.)
10910        Thread worker = new Thread("Error dump: " + dropboxTag) {
10911            @Override
10912            public void run() {
10913                if (report != null) {
10914                    sb.append(report);
10915                }
10916                if (logFile != null) {
10917                    try {
10918                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10919                                    "\n\n[[TRUNCATED]]"));
10920                    } catch (IOException e) {
10921                        Slog.e(TAG, "Error reading " + logFile, e);
10922                    }
10923                }
10924                if (crashInfo != null && crashInfo.stackTrace != null) {
10925                    sb.append(crashInfo.stackTrace);
10926                }
10927
10928                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10929                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10930                if (lines > 0) {
10931                    sb.append("\n");
10932
10933                    // Merge several logcat streams, and take the last N lines
10934                    InputStreamReader input = null;
10935                    try {
10936                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10937                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10938                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10939
10940                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10941                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10942                        input = new InputStreamReader(logcat.getInputStream());
10943
10944                        int num;
10945                        char[] buf = new char[8192];
10946                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10947                    } catch (IOException e) {
10948                        Slog.e(TAG, "Error running logcat", e);
10949                    } finally {
10950                        if (input != null) try { input.close(); } catch (IOException e) {}
10951                    }
10952                }
10953
10954                dbox.addText(dropboxTag, sb.toString());
10955            }
10956        };
10957
10958        if (process == null) {
10959            // If process is null, we are being called from some internal code
10960            // and may be about to die -- run this synchronously.
10961            worker.run();
10962        } else {
10963            worker.start();
10964        }
10965    }
10966
10967    /**
10968     * Bring up the "unexpected error" dialog box for a crashing app.
10969     * Deal with edge cases (intercepts from instrumented applications,
10970     * ActivityController, error intent receivers, that sort of thing).
10971     * @param r the application crashing
10972     * @param crashInfo describing the failure
10973     */
10974    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10975        long timeMillis = System.currentTimeMillis();
10976        String shortMsg = crashInfo.exceptionClassName;
10977        String longMsg = crashInfo.exceptionMessage;
10978        String stackTrace = crashInfo.stackTrace;
10979        if (shortMsg != null && longMsg != null) {
10980            longMsg = shortMsg + ": " + longMsg;
10981        } else if (shortMsg != null) {
10982            longMsg = shortMsg;
10983        }
10984
10985        AppErrorResult result = new AppErrorResult();
10986        synchronized (this) {
10987            if (mController != null) {
10988                try {
10989                    String name = r != null ? r.processName : null;
10990                    int pid = r != null ? r.pid : Binder.getCallingPid();
10991                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10992                    if (!mController.appCrashed(name, pid,
10993                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10994                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
10995                                && "Native crash".equals(crashInfo.exceptionClassName)) {
10996                            Slog.w(TAG, "Skip killing native crashed app " + name
10997                                    + "(" + pid + ") during testing");
10998                        } else {
10999                            Slog.w(TAG, "Force-killing crashed app " + name
11000                                    + " at watcher's request");
11001                            Process.killProcess(pid);
11002                            if (r != null) {
11003                                Process.killProcessGroup(uid, pid);
11004                            }
11005                        }
11006                        return;
11007                    }
11008                } catch (RemoteException e) {
11009                    mController = null;
11010                    Watchdog.getInstance().setActivityController(null);
11011                }
11012            }
11013
11014            final long origId = Binder.clearCallingIdentity();
11015
11016            // If this process is running instrumentation, finish it.
11017            if (r != null && r.instrumentationClass != null) {
11018                Slog.w(TAG, "Error in app " + r.processName
11019                      + " running instrumentation " + r.instrumentationClass + ":");
11020                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11021                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11022                Bundle info = new Bundle();
11023                info.putString("shortMsg", shortMsg);
11024                info.putString("longMsg", longMsg);
11025                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11026                Binder.restoreCallingIdentity(origId);
11027                return;
11028            }
11029
11030            // If we can't identify the process or it's already exceeded its crash quota,
11031            // quit right away without showing a crash dialog.
11032            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11033                Binder.restoreCallingIdentity(origId);
11034                return;
11035            }
11036
11037            Message msg = Message.obtain();
11038            msg.what = SHOW_ERROR_MSG;
11039            HashMap data = new HashMap();
11040            data.put("result", result);
11041            data.put("app", r);
11042            msg.obj = data;
11043            mHandler.sendMessage(msg);
11044
11045            Binder.restoreCallingIdentity(origId);
11046        }
11047
11048        int res = result.get();
11049
11050        Intent appErrorIntent = null;
11051        synchronized (this) {
11052            if (r != null && !r.isolated) {
11053                // XXX Can't keep track of crash time for isolated processes,
11054                // since they don't have a persistent identity.
11055                mProcessCrashTimes.put(r.info.processName, r.uid,
11056                        SystemClock.uptimeMillis());
11057            }
11058            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11059                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11060            }
11061        }
11062
11063        if (appErrorIntent != null) {
11064            try {
11065                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11066            } catch (ActivityNotFoundException e) {
11067                Slog.w(TAG, "bug report receiver dissappeared", e);
11068            }
11069        }
11070    }
11071
11072    Intent createAppErrorIntentLocked(ProcessRecord r,
11073            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11074        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11075        if (report == null) {
11076            return null;
11077        }
11078        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11079        result.setComponent(r.errorReportReceiver);
11080        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11081        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11082        return result;
11083    }
11084
11085    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11086            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11087        if (r.errorReportReceiver == null) {
11088            return null;
11089        }
11090
11091        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11092            return null;
11093        }
11094
11095        ApplicationErrorReport report = new ApplicationErrorReport();
11096        report.packageName = r.info.packageName;
11097        report.installerPackageName = r.errorReportReceiver.getPackageName();
11098        report.processName = r.processName;
11099        report.time = timeMillis;
11100        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11101
11102        if (r.crashing || r.forceCrashReport) {
11103            report.type = ApplicationErrorReport.TYPE_CRASH;
11104            report.crashInfo = crashInfo;
11105        } else if (r.notResponding) {
11106            report.type = ApplicationErrorReport.TYPE_ANR;
11107            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11108
11109            report.anrInfo.activity = r.notRespondingReport.tag;
11110            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11111            report.anrInfo.info = r.notRespondingReport.longMsg;
11112        }
11113
11114        return report;
11115    }
11116
11117    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11118        enforceNotIsolatedCaller("getProcessesInErrorState");
11119        // assume our apps are happy - lazy create the list
11120        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11121
11122        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11123                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11124        int userId = UserHandle.getUserId(Binder.getCallingUid());
11125
11126        synchronized (this) {
11127
11128            // iterate across all processes
11129            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11130                ProcessRecord app = mLruProcesses.get(i);
11131                if (!allUsers && app.userId != userId) {
11132                    continue;
11133                }
11134                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11135                    // This one's in trouble, so we'll generate a report for it
11136                    // crashes are higher priority (in case there's a crash *and* an anr)
11137                    ActivityManager.ProcessErrorStateInfo report = null;
11138                    if (app.crashing) {
11139                        report = app.crashingReport;
11140                    } else if (app.notResponding) {
11141                        report = app.notRespondingReport;
11142                    }
11143
11144                    if (report != null) {
11145                        if (errList == null) {
11146                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11147                        }
11148                        errList.add(report);
11149                    } else {
11150                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11151                                " crashing = " + app.crashing +
11152                                " notResponding = " + app.notResponding);
11153                    }
11154                }
11155            }
11156        }
11157
11158        return errList;
11159    }
11160
11161    static int procStateToImportance(int procState, int memAdj,
11162            ActivityManager.RunningAppProcessInfo currApp) {
11163        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11164        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11165            currApp.lru = memAdj;
11166        } else {
11167            currApp.lru = 0;
11168        }
11169        return imp;
11170    }
11171
11172    private void fillInProcMemInfo(ProcessRecord app,
11173            ActivityManager.RunningAppProcessInfo outInfo) {
11174        outInfo.pid = app.pid;
11175        outInfo.uid = app.info.uid;
11176        if (mHeavyWeightProcess == app) {
11177            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11178        }
11179        if (app.persistent) {
11180            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11181        }
11182        if (app.activities.size() > 0) {
11183            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11184        }
11185        outInfo.lastTrimLevel = app.trimMemoryLevel;
11186        int adj = app.curAdj;
11187        int procState = app.curProcState;
11188        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11189        outInfo.importanceReasonCode = app.adjTypeCode;
11190        outInfo.processState = app.curProcState;
11191    }
11192
11193    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11194        enforceNotIsolatedCaller("getRunningAppProcesses");
11195        // Lazy instantiation of list
11196        List<ActivityManager.RunningAppProcessInfo> runList = null;
11197        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11198                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11199        int userId = UserHandle.getUserId(Binder.getCallingUid());
11200        synchronized (this) {
11201            // Iterate across all processes
11202            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11203                ProcessRecord app = mLruProcesses.get(i);
11204                if (!allUsers && app.userId != userId) {
11205                    continue;
11206                }
11207                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11208                    // Generate process state info for running application
11209                    ActivityManager.RunningAppProcessInfo currApp =
11210                        new ActivityManager.RunningAppProcessInfo(app.processName,
11211                                app.pid, app.getPackageList());
11212                    fillInProcMemInfo(app, currApp);
11213                    if (app.adjSource instanceof ProcessRecord) {
11214                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11215                        currApp.importanceReasonImportance =
11216                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11217                                        app.adjSourceProcState);
11218                    } else if (app.adjSource instanceof ActivityRecord) {
11219                        ActivityRecord r = (ActivityRecord)app.adjSource;
11220                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11221                    }
11222                    if (app.adjTarget instanceof ComponentName) {
11223                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11224                    }
11225                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11226                    //        + " lru=" + currApp.lru);
11227                    if (runList == null) {
11228                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11229                    }
11230                    runList.add(currApp);
11231                }
11232            }
11233        }
11234        return runList;
11235    }
11236
11237    public List<ApplicationInfo> getRunningExternalApplications() {
11238        enforceNotIsolatedCaller("getRunningExternalApplications");
11239        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11240        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11241        if (runningApps != null && runningApps.size() > 0) {
11242            Set<String> extList = new HashSet<String>();
11243            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11244                if (app.pkgList != null) {
11245                    for (String pkg : app.pkgList) {
11246                        extList.add(pkg);
11247                    }
11248                }
11249            }
11250            IPackageManager pm = AppGlobals.getPackageManager();
11251            for (String pkg : extList) {
11252                try {
11253                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11254                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11255                        retList.add(info);
11256                    }
11257                } catch (RemoteException e) {
11258                }
11259            }
11260        }
11261        return retList;
11262    }
11263
11264    @Override
11265    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11266        enforceNotIsolatedCaller("getMyMemoryState");
11267        synchronized (this) {
11268            ProcessRecord proc;
11269            synchronized (mPidsSelfLocked) {
11270                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11271            }
11272            fillInProcMemInfo(proc, outInfo);
11273        }
11274    }
11275
11276    @Override
11277    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11278        if (checkCallingPermission(android.Manifest.permission.DUMP)
11279                != PackageManager.PERMISSION_GRANTED) {
11280            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11281                    + Binder.getCallingPid()
11282                    + ", uid=" + Binder.getCallingUid()
11283                    + " without permission "
11284                    + android.Manifest.permission.DUMP);
11285            return;
11286        }
11287
11288        boolean dumpAll = false;
11289        boolean dumpClient = false;
11290        String dumpPackage = null;
11291
11292        int opti = 0;
11293        while (opti < args.length) {
11294            String opt = args[opti];
11295            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11296                break;
11297            }
11298            opti++;
11299            if ("-a".equals(opt)) {
11300                dumpAll = true;
11301            } else if ("-c".equals(opt)) {
11302                dumpClient = true;
11303            } else if ("-h".equals(opt)) {
11304                pw.println("Activity manager dump options:");
11305                pw.println("  [-a] [-c] [-h] [cmd] ...");
11306                pw.println("  cmd may be one of:");
11307                pw.println("    a[ctivities]: activity stack state");
11308                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11309                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11310                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11311                pw.println("    o[om]: out of memory management");
11312                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11313                pw.println("    provider [COMP_SPEC]: provider client-side state");
11314                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11315                pw.println("    service [COMP_SPEC]: service client-side state");
11316                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11317                pw.println("    all: dump all activities");
11318                pw.println("    top: dump the top activity");
11319                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11320                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11321                pw.println("    a partial substring in a component name, a");
11322                pw.println("    hex object identifier.");
11323                pw.println("  -a: include all available server state.");
11324                pw.println("  -c: include client state.");
11325                return;
11326            } else {
11327                pw.println("Unknown argument: " + opt + "; use -h for help");
11328            }
11329        }
11330
11331        long origId = Binder.clearCallingIdentity();
11332        boolean more = false;
11333        // Is the caller requesting to dump a particular piece of data?
11334        if (opti < args.length) {
11335            String cmd = args[opti];
11336            opti++;
11337            if ("activities".equals(cmd) || "a".equals(cmd)) {
11338                synchronized (this) {
11339                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11340                }
11341            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11342                String[] newArgs;
11343                String name;
11344                if (opti >= args.length) {
11345                    name = null;
11346                    newArgs = EMPTY_STRING_ARRAY;
11347                } else {
11348                    name = args[opti];
11349                    opti++;
11350                    newArgs = new String[args.length - opti];
11351                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11352                            args.length - opti);
11353                }
11354                synchronized (this) {
11355                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11356                }
11357            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11358                String[] newArgs;
11359                String name;
11360                if (opti >= args.length) {
11361                    name = null;
11362                    newArgs = EMPTY_STRING_ARRAY;
11363                } else {
11364                    name = args[opti];
11365                    opti++;
11366                    newArgs = new String[args.length - opti];
11367                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11368                            args.length - opti);
11369                }
11370                synchronized (this) {
11371                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11372                }
11373            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11374                String[] newArgs;
11375                String name;
11376                if (opti >= args.length) {
11377                    name = null;
11378                    newArgs = EMPTY_STRING_ARRAY;
11379                } else {
11380                    name = args[opti];
11381                    opti++;
11382                    newArgs = new String[args.length - opti];
11383                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11384                            args.length - opti);
11385                }
11386                synchronized (this) {
11387                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11388                }
11389            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11390                synchronized (this) {
11391                    dumpOomLocked(fd, pw, args, opti, true);
11392                }
11393            } else if ("provider".equals(cmd)) {
11394                String[] newArgs;
11395                String name;
11396                if (opti >= args.length) {
11397                    name = null;
11398                    newArgs = EMPTY_STRING_ARRAY;
11399                } else {
11400                    name = args[opti];
11401                    opti++;
11402                    newArgs = new String[args.length - opti];
11403                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11404                }
11405                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11406                    pw.println("No providers match: " + name);
11407                    pw.println("Use -h for help.");
11408                }
11409            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11410                synchronized (this) {
11411                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11412                }
11413            } else if ("service".equals(cmd)) {
11414                String[] newArgs;
11415                String name;
11416                if (opti >= args.length) {
11417                    name = null;
11418                    newArgs = EMPTY_STRING_ARRAY;
11419                } else {
11420                    name = args[opti];
11421                    opti++;
11422                    newArgs = new String[args.length - opti];
11423                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11424                            args.length - opti);
11425                }
11426                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11427                    pw.println("No services match: " + name);
11428                    pw.println("Use -h for help.");
11429                }
11430            } else if ("package".equals(cmd)) {
11431                String[] newArgs;
11432                if (opti >= args.length) {
11433                    pw.println("package: no package name specified");
11434                    pw.println("Use -h for help.");
11435                } else {
11436                    dumpPackage = args[opti];
11437                    opti++;
11438                    newArgs = new String[args.length - opti];
11439                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11440                            args.length - opti);
11441                    args = newArgs;
11442                    opti = 0;
11443                    more = true;
11444                }
11445            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11446                synchronized (this) {
11447                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11448                }
11449            } else {
11450                // Dumping a single activity?
11451                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11452                    pw.println("Bad activity command, or no activities match: " + cmd);
11453                    pw.println("Use -h for help.");
11454                }
11455            }
11456            if (!more) {
11457                Binder.restoreCallingIdentity(origId);
11458                return;
11459            }
11460        }
11461
11462        // No piece of data specified, dump everything.
11463        synchronized (this) {
11464            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11465            pw.println();
11466            if (dumpAll) {
11467                pw.println("-------------------------------------------------------------------------------");
11468            }
11469            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11470            pw.println();
11471            if (dumpAll) {
11472                pw.println("-------------------------------------------------------------------------------");
11473            }
11474            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11475            pw.println();
11476            if (dumpAll) {
11477                pw.println("-------------------------------------------------------------------------------");
11478            }
11479            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11480            pw.println();
11481            if (dumpAll) {
11482                pw.println("-------------------------------------------------------------------------------");
11483            }
11484            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11485            pw.println();
11486            if (dumpAll) {
11487                pw.println("-------------------------------------------------------------------------------");
11488            }
11489            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11490        }
11491        Binder.restoreCallingIdentity(origId);
11492    }
11493
11494    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11495            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11496        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11497
11498        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11499                dumpPackage);
11500        boolean needSep = printedAnything;
11501
11502        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11503                dumpPackage, needSep, "  mFocusedActivity: ");
11504        if (printed) {
11505            printedAnything = true;
11506            needSep = false;
11507        }
11508
11509        if (dumpPackage == null) {
11510            if (needSep) {
11511                pw.println();
11512            }
11513            needSep = true;
11514            printedAnything = true;
11515            mStackSupervisor.dump(pw, "  ");
11516        }
11517
11518        if (mRecentTasks.size() > 0) {
11519            boolean printedHeader = false;
11520
11521            final int N = mRecentTasks.size();
11522            for (int i=0; i<N; i++) {
11523                TaskRecord tr = mRecentTasks.get(i);
11524                if (dumpPackage != null) {
11525                    if (tr.realActivity == null ||
11526                            !dumpPackage.equals(tr.realActivity)) {
11527                        continue;
11528                    }
11529                }
11530                if (!printedHeader) {
11531                    if (needSep) {
11532                        pw.println();
11533                    }
11534                    pw.println("  Recent tasks:");
11535                    printedHeader = true;
11536                    printedAnything = true;
11537                }
11538                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11539                        pw.println(tr);
11540                if (dumpAll) {
11541                    mRecentTasks.get(i).dump(pw, "    ");
11542                }
11543            }
11544        }
11545
11546        if (!printedAnything) {
11547            pw.println("  (nothing)");
11548        }
11549    }
11550
11551    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11552            int opti, boolean dumpAll, String dumpPackage) {
11553        boolean needSep = false;
11554        boolean printedAnything = false;
11555        int numPers = 0;
11556
11557        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11558
11559        if (dumpAll) {
11560            final int NP = mProcessNames.getMap().size();
11561            for (int ip=0; ip<NP; ip++) {
11562                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11563                final int NA = procs.size();
11564                for (int ia=0; ia<NA; ia++) {
11565                    ProcessRecord r = procs.valueAt(ia);
11566                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11567                        continue;
11568                    }
11569                    if (!needSep) {
11570                        pw.println("  All known processes:");
11571                        needSep = true;
11572                        printedAnything = true;
11573                    }
11574                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11575                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11576                        pw.print(" "); pw.println(r);
11577                    r.dump(pw, "    ");
11578                    if (r.persistent) {
11579                        numPers++;
11580                    }
11581                }
11582            }
11583        }
11584
11585        if (mIsolatedProcesses.size() > 0) {
11586            boolean printed = false;
11587            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11588                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11589                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11590                    continue;
11591                }
11592                if (!printed) {
11593                    if (needSep) {
11594                        pw.println();
11595                    }
11596                    pw.println("  Isolated process list (sorted by uid):");
11597                    printedAnything = true;
11598                    printed = true;
11599                    needSep = true;
11600                }
11601                pw.println(String.format("%sIsolated #%2d: %s",
11602                        "    ", i, r.toString()));
11603            }
11604        }
11605
11606        if (mLruProcesses.size() > 0) {
11607            if (needSep) {
11608                pw.println();
11609            }
11610            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11611                    pw.print(" total, non-act at ");
11612                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11613                    pw.print(", non-svc at ");
11614                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11615                    pw.println("):");
11616            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11617            needSep = true;
11618            printedAnything = true;
11619        }
11620
11621        if (dumpAll || dumpPackage != null) {
11622            synchronized (mPidsSelfLocked) {
11623                boolean printed = false;
11624                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11625                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11626                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11627                        continue;
11628                    }
11629                    if (!printed) {
11630                        if (needSep) pw.println();
11631                        needSep = true;
11632                        pw.println("  PID mappings:");
11633                        printed = true;
11634                        printedAnything = true;
11635                    }
11636                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11637                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11638                }
11639            }
11640        }
11641
11642        if (mForegroundProcesses.size() > 0) {
11643            synchronized (mPidsSelfLocked) {
11644                boolean printed = false;
11645                for (int i=0; i<mForegroundProcesses.size(); i++) {
11646                    ProcessRecord r = mPidsSelfLocked.get(
11647                            mForegroundProcesses.valueAt(i).pid);
11648                    if (dumpPackage != null && (r == null
11649                            || !r.pkgList.containsKey(dumpPackage))) {
11650                        continue;
11651                    }
11652                    if (!printed) {
11653                        if (needSep) pw.println();
11654                        needSep = true;
11655                        pw.println("  Foreground Processes:");
11656                        printed = true;
11657                        printedAnything = true;
11658                    }
11659                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11660                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11661                }
11662            }
11663        }
11664
11665        if (mPersistentStartingProcesses.size() > 0) {
11666            if (needSep) pw.println();
11667            needSep = true;
11668            printedAnything = true;
11669            pw.println("  Persisent processes that are starting:");
11670            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11671                    "Starting Norm", "Restarting PERS", dumpPackage);
11672        }
11673
11674        if (mRemovedProcesses.size() > 0) {
11675            if (needSep) pw.println();
11676            needSep = true;
11677            printedAnything = true;
11678            pw.println("  Processes that are being removed:");
11679            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11680                    "Removed Norm", "Removed PERS", dumpPackage);
11681        }
11682
11683        if (mProcessesOnHold.size() > 0) {
11684            if (needSep) pw.println();
11685            needSep = true;
11686            printedAnything = true;
11687            pw.println("  Processes that are on old until the system is ready:");
11688            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11689                    "OnHold Norm", "OnHold PERS", dumpPackage);
11690        }
11691
11692        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11693
11694        if (mProcessCrashTimes.getMap().size() > 0) {
11695            boolean printed = false;
11696            long now = SystemClock.uptimeMillis();
11697            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11698            final int NP = pmap.size();
11699            for (int ip=0; ip<NP; ip++) {
11700                String pname = pmap.keyAt(ip);
11701                SparseArray<Long> uids = pmap.valueAt(ip);
11702                final int N = uids.size();
11703                for (int i=0; i<N; i++) {
11704                    int puid = uids.keyAt(i);
11705                    ProcessRecord r = mProcessNames.get(pname, puid);
11706                    if (dumpPackage != null && (r == null
11707                            || !r.pkgList.containsKey(dumpPackage))) {
11708                        continue;
11709                    }
11710                    if (!printed) {
11711                        if (needSep) pw.println();
11712                        needSep = true;
11713                        pw.println("  Time since processes crashed:");
11714                        printed = true;
11715                        printedAnything = true;
11716                    }
11717                    pw.print("    Process "); pw.print(pname);
11718                            pw.print(" uid "); pw.print(puid);
11719                            pw.print(": last crashed ");
11720                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11721                            pw.println(" ago");
11722                }
11723            }
11724        }
11725
11726        if (mBadProcesses.getMap().size() > 0) {
11727            boolean printed = false;
11728            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11729            final int NP = pmap.size();
11730            for (int ip=0; ip<NP; ip++) {
11731                String pname = pmap.keyAt(ip);
11732                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11733                final int N = uids.size();
11734                for (int i=0; i<N; i++) {
11735                    int puid = uids.keyAt(i);
11736                    ProcessRecord r = mProcessNames.get(pname, puid);
11737                    if (dumpPackage != null && (r == null
11738                            || !r.pkgList.containsKey(dumpPackage))) {
11739                        continue;
11740                    }
11741                    if (!printed) {
11742                        if (needSep) pw.println();
11743                        needSep = true;
11744                        pw.println("  Bad processes:");
11745                        printedAnything = true;
11746                    }
11747                    BadProcessInfo info = uids.valueAt(i);
11748                    pw.print("    Bad process "); pw.print(pname);
11749                            pw.print(" uid "); pw.print(puid);
11750                            pw.print(": crashed at time "); pw.println(info.time);
11751                    if (info.shortMsg != null) {
11752                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11753                    }
11754                    if (info.longMsg != null) {
11755                        pw.print("      Long msg: "); pw.println(info.longMsg);
11756                    }
11757                    if (info.stack != null) {
11758                        pw.println("      Stack:");
11759                        int lastPos = 0;
11760                        for (int pos=0; pos<info.stack.length(); pos++) {
11761                            if (info.stack.charAt(pos) == '\n') {
11762                                pw.print("        ");
11763                                pw.write(info.stack, lastPos, pos-lastPos);
11764                                pw.println();
11765                                lastPos = pos+1;
11766                            }
11767                        }
11768                        if (lastPos < info.stack.length()) {
11769                            pw.print("        ");
11770                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11771                            pw.println();
11772                        }
11773                    }
11774                }
11775            }
11776        }
11777
11778        if (dumpPackage == null) {
11779            pw.println();
11780            needSep = false;
11781            pw.println("  mStartedUsers:");
11782            for (int i=0; i<mStartedUsers.size(); i++) {
11783                UserStartedState uss = mStartedUsers.valueAt(i);
11784                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11785                        pw.print(": "); uss.dump("", pw);
11786            }
11787            pw.print("  mStartedUserArray: [");
11788            for (int i=0; i<mStartedUserArray.length; i++) {
11789                if (i > 0) pw.print(", ");
11790                pw.print(mStartedUserArray[i]);
11791            }
11792            pw.println("]");
11793            pw.print("  mUserLru: [");
11794            for (int i=0; i<mUserLru.size(); i++) {
11795                if (i > 0) pw.print(", ");
11796                pw.print(mUserLru.get(i));
11797            }
11798            pw.println("]");
11799            if (dumpAll) {
11800                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11801            }
11802            synchronized (mUserProfileGroupIdsSelfLocked) {
11803                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11804                    pw.println("  mUserProfileGroupIds:");
11805                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11806                        pw.print("    User #");
11807                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11808                        pw.print(" -> profile #");
11809                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11810                    }
11811                }
11812            }
11813        }
11814        if (mHomeProcess != null && (dumpPackage == null
11815                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11816            if (needSep) {
11817                pw.println();
11818                needSep = false;
11819            }
11820            pw.println("  mHomeProcess: " + mHomeProcess);
11821        }
11822        if (mPreviousProcess != null && (dumpPackage == null
11823                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11824            if (needSep) {
11825                pw.println();
11826                needSep = false;
11827            }
11828            pw.println("  mPreviousProcess: " + mPreviousProcess);
11829        }
11830        if (dumpAll) {
11831            StringBuilder sb = new StringBuilder(128);
11832            sb.append("  mPreviousProcessVisibleTime: ");
11833            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11834            pw.println(sb);
11835        }
11836        if (mHeavyWeightProcess != null && (dumpPackage == null
11837                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11838            if (needSep) {
11839                pw.println();
11840                needSep = false;
11841            }
11842            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11843        }
11844        if (dumpPackage == null) {
11845            pw.println("  mConfiguration: " + mConfiguration);
11846        }
11847        if (dumpAll) {
11848            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11849            if (mCompatModePackages.getPackages().size() > 0) {
11850                boolean printed = false;
11851                for (Map.Entry<String, Integer> entry
11852                        : mCompatModePackages.getPackages().entrySet()) {
11853                    String pkg = entry.getKey();
11854                    int mode = entry.getValue();
11855                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11856                        continue;
11857                    }
11858                    if (!printed) {
11859                        pw.println("  mScreenCompatPackages:");
11860                        printed = true;
11861                    }
11862                    pw.print("    "); pw.print(pkg); pw.print(": ");
11863                            pw.print(mode); pw.println();
11864                }
11865            }
11866        }
11867        if (dumpPackage == null) {
11868            if (mSleeping || mWentToSleep || mLockScreenShown) {
11869                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11870                        + " mLockScreenShown " + mLockScreenShown);
11871            }
11872            if (mShuttingDown || mRunningVoice) {
11873                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11874            }
11875        }
11876        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11877                || mOrigWaitForDebugger) {
11878            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11879                    || dumpPackage.equals(mOrigDebugApp)) {
11880                if (needSep) {
11881                    pw.println();
11882                    needSep = false;
11883                }
11884                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11885                        + " mDebugTransient=" + mDebugTransient
11886                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11887            }
11888        }
11889        if (mOpenGlTraceApp != null) {
11890            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11891                if (needSep) {
11892                    pw.println();
11893                    needSep = false;
11894                }
11895                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11896            }
11897        }
11898        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11899                || mProfileFd != null) {
11900            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11901                if (needSep) {
11902                    pw.println();
11903                    needSep = false;
11904                }
11905                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11906                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11907                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11908                        + mAutoStopProfiler);
11909            }
11910        }
11911        if (dumpPackage == null) {
11912            if (mAlwaysFinishActivities || mController != null) {
11913                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11914                        + " mController=" + mController);
11915            }
11916            if (dumpAll) {
11917                pw.println("  Total persistent processes: " + numPers);
11918                pw.println("  mProcessesReady=" + mProcessesReady
11919                        + " mSystemReady=" + mSystemReady);
11920                pw.println("  mBooting=" + mBooting
11921                        + " mBooted=" + mBooted
11922                        + " mFactoryTest=" + mFactoryTest);
11923                pw.print("  mLastPowerCheckRealtime=");
11924                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11925                        pw.println("");
11926                pw.print("  mLastPowerCheckUptime=");
11927                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11928                        pw.println("");
11929                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11930                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11931                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11932                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11933                        + " (" + mLruProcesses.size() + " total)"
11934                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11935                        + " mNumServiceProcs=" + mNumServiceProcs
11936                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11937                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11938                        + " mLastMemoryLevel" + mLastMemoryLevel
11939                        + " mLastNumProcesses" + mLastNumProcesses);
11940                long now = SystemClock.uptimeMillis();
11941                pw.print("  mLastIdleTime=");
11942                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11943                        pw.print(" mLowRamSinceLastIdle=");
11944                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11945                        pw.println();
11946            }
11947        }
11948
11949        if (!printedAnything) {
11950            pw.println("  (nothing)");
11951        }
11952    }
11953
11954    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11955            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11956        if (mProcessesToGc.size() > 0) {
11957            boolean printed = false;
11958            long now = SystemClock.uptimeMillis();
11959            for (int i=0; i<mProcessesToGc.size(); i++) {
11960                ProcessRecord proc = mProcessesToGc.get(i);
11961                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11962                    continue;
11963                }
11964                if (!printed) {
11965                    if (needSep) pw.println();
11966                    needSep = true;
11967                    pw.println("  Processes that are waiting to GC:");
11968                    printed = true;
11969                }
11970                pw.print("    Process "); pw.println(proc);
11971                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11972                        pw.print(", last gced=");
11973                        pw.print(now-proc.lastRequestedGc);
11974                        pw.print(" ms ago, last lowMem=");
11975                        pw.print(now-proc.lastLowMemory);
11976                        pw.println(" ms ago");
11977
11978            }
11979        }
11980        return needSep;
11981    }
11982
11983    void printOomLevel(PrintWriter pw, String name, int adj) {
11984        pw.print("    ");
11985        if (adj >= 0) {
11986            pw.print(' ');
11987            if (adj < 10) pw.print(' ');
11988        } else {
11989            if (adj > -10) pw.print(' ');
11990        }
11991        pw.print(adj);
11992        pw.print(": ");
11993        pw.print(name);
11994        pw.print(" (");
11995        pw.print(mProcessList.getMemLevel(adj)/1024);
11996        pw.println(" kB)");
11997    }
11998
11999    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12000            int opti, boolean dumpAll) {
12001        boolean needSep = false;
12002
12003        if (mLruProcesses.size() > 0) {
12004            if (needSep) pw.println();
12005            needSep = true;
12006            pw.println("  OOM levels:");
12007            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12008            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12009            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12010            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12011            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12012            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12013            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12014            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12015            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12016            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12017            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12018            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12019            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12020
12021            if (needSep) pw.println();
12022            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12023                    pw.print(" total, non-act at ");
12024                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12025                    pw.print(", non-svc at ");
12026                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12027                    pw.println("):");
12028            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12029            needSep = true;
12030        }
12031
12032        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12033
12034        pw.println();
12035        pw.println("  mHomeProcess: " + mHomeProcess);
12036        pw.println("  mPreviousProcess: " + mPreviousProcess);
12037        if (mHeavyWeightProcess != null) {
12038            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12039        }
12040
12041        return true;
12042    }
12043
12044    /**
12045     * There are three ways to call this:
12046     *  - no provider specified: dump all the providers
12047     *  - a flattened component name that matched an existing provider was specified as the
12048     *    first arg: dump that one provider
12049     *  - the first arg isn't the flattened component name of an existing provider:
12050     *    dump all providers whose component contains the first arg as a substring
12051     */
12052    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12053            int opti, boolean dumpAll) {
12054        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12055    }
12056
12057    static class ItemMatcher {
12058        ArrayList<ComponentName> components;
12059        ArrayList<String> strings;
12060        ArrayList<Integer> objects;
12061        boolean all;
12062
12063        ItemMatcher() {
12064            all = true;
12065        }
12066
12067        void build(String name) {
12068            ComponentName componentName = ComponentName.unflattenFromString(name);
12069            if (componentName != null) {
12070                if (components == null) {
12071                    components = new ArrayList<ComponentName>();
12072                }
12073                components.add(componentName);
12074                all = false;
12075            } else {
12076                int objectId = 0;
12077                // Not a '/' separated full component name; maybe an object ID?
12078                try {
12079                    objectId = Integer.parseInt(name, 16);
12080                    if (objects == null) {
12081                        objects = new ArrayList<Integer>();
12082                    }
12083                    objects.add(objectId);
12084                    all = false;
12085                } catch (RuntimeException e) {
12086                    // Not an integer; just do string match.
12087                    if (strings == null) {
12088                        strings = new ArrayList<String>();
12089                    }
12090                    strings.add(name);
12091                    all = false;
12092                }
12093            }
12094        }
12095
12096        int build(String[] args, int opti) {
12097            for (; opti<args.length; opti++) {
12098                String name = args[opti];
12099                if ("--".equals(name)) {
12100                    return opti+1;
12101                }
12102                build(name);
12103            }
12104            return opti;
12105        }
12106
12107        boolean match(Object object, ComponentName comp) {
12108            if (all) {
12109                return true;
12110            }
12111            if (components != null) {
12112                for (int i=0; i<components.size(); i++) {
12113                    if (components.get(i).equals(comp)) {
12114                        return true;
12115                    }
12116                }
12117            }
12118            if (objects != null) {
12119                for (int i=0; i<objects.size(); i++) {
12120                    if (System.identityHashCode(object) == objects.get(i)) {
12121                        return true;
12122                    }
12123                }
12124            }
12125            if (strings != null) {
12126                String flat = comp.flattenToString();
12127                for (int i=0; i<strings.size(); i++) {
12128                    if (flat.contains(strings.get(i))) {
12129                        return true;
12130                    }
12131                }
12132            }
12133            return false;
12134        }
12135    }
12136
12137    /**
12138     * There are three things that cmd can be:
12139     *  - a flattened component name that matches an existing activity
12140     *  - the cmd arg isn't the flattened component name of an existing activity:
12141     *    dump all activity whose component contains the cmd as a substring
12142     *  - A hex number of the ActivityRecord object instance.
12143     */
12144    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12145            int opti, boolean dumpAll) {
12146        ArrayList<ActivityRecord> activities;
12147
12148        synchronized (this) {
12149            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12150        }
12151
12152        if (activities.size() <= 0) {
12153            return false;
12154        }
12155
12156        String[] newArgs = new String[args.length - opti];
12157        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12158
12159        TaskRecord lastTask = null;
12160        boolean needSep = false;
12161        for (int i=activities.size()-1; i>=0; i--) {
12162            ActivityRecord r = activities.get(i);
12163            if (needSep) {
12164                pw.println();
12165            }
12166            needSep = true;
12167            synchronized (this) {
12168                if (lastTask != r.task) {
12169                    lastTask = r.task;
12170                    pw.print("TASK "); pw.print(lastTask.affinity);
12171                            pw.print(" id="); pw.println(lastTask.taskId);
12172                    if (dumpAll) {
12173                        lastTask.dump(pw, "  ");
12174                    }
12175                }
12176            }
12177            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12178        }
12179        return true;
12180    }
12181
12182    /**
12183     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12184     * there is a thread associated with the activity.
12185     */
12186    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12187            final ActivityRecord r, String[] args, boolean dumpAll) {
12188        String innerPrefix = prefix + "  ";
12189        synchronized (this) {
12190            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12191                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12192                    pw.print(" pid=");
12193                    if (r.app != null) pw.println(r.app.pid);
12194                    else pw.println("(not running)");
12195            if (dumpAll) {
12196                r.dump(pw, innerPrefix);
12197            }
12198        }
12199        if (r.app != null && r.app.thread != null) {
12200            // flush anything that is already in the PrintWriter since the thread is going
12201            // to write to the file descriptor directly
12202            pw.flush();
12203            try {
12204                TransferPipe tp = new TransferPipe();
12205                try {
12206                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12207                            r.appToken, innerPrefix, args);
12208                    tp.go(fd);
12209                } finally {
12210                    tp.kill();
12211                }
12212            } catch (IOException e) {
12213                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12214            } catch (RemoteException e) {
12215                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12216            }
12217        }
12218    }
12219
12220    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12221            int opti, boolean dumpAll, String dumpPackage) {
12222        boolean needSep = false;
12223        boolean onlyHistory = false;
12224        boolean printedAnything = false;
12225
12226        if ("history".equals(dumpPackage)) {
12227            if (opti < args.length && "-s".equals(args[opti])) {
12228                dumpAll = false;
12229            }
12230            onlyHistory = true;
12231            dumpPackage = null;
12232        }
12233
12234        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12235        if (!onlyHistory && dumpAll) {
12236            if (mRegisteredReceivers.size() > 0) {
12237                boolean printed = false;
12238                Iterator it = mRegisteredReceivers.values().iterator();
12239                while (it.hasNext()) {
12240                    ReceiverList r = (ReceiverList)it.next();
12241                    if (dumpPackage != null && (r.app == null ||
12242                            !dumpPackage.equals(r.app.info.packageName))) {
12243                        continue;
12244                    }
12245                    if (!printed) {
12246                        pw.println("  Registered Receivers:");
12247                        needSep = true;
12248                        printed = true;
12249                        printedAnything = true;
12250                    }
12251                    pw.print("  * "); pw.println(r);
12252                    r.dump(pw, "    ");
12253                }
12254            }
12255
12256            if (mReceiverResolver.dump(pw, needSep ?
12257                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12258                    "    ", dumpPackage, false)) {
12259                needSep = true;
12260                printedAnything = true;
12261            }
12262        }
12263
12264        for (BroadcastQueue q : mBroadcastQueues) {
12265            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12266            printedAnything |= needSep;
12267        }
12268
12269        needSep = true;
12270
12271        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12272            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12273                if (needSep) {
12274                    pw.println();
12275                }
12276                needSep = true;
12277                printedAnything = true;
12278                pw.print("  Sticky broadcasts for user ");
12279                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12280                StringBuilder sb = new StringBuilder(128);
12281                for (Map.Entry<String, ArrayList<Intent>> ent
12282                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12283                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12284                    if (dumpAll) {
12285                        pw.println(":");
12286                        ArrayList<Intent> intents = ent.getValue();
12287                        final int N = intents.size();
12288                        for (int i=0; i<N; i++) {
12289                            sb.setLength(0);
12290                            sb.append("    Intent: ");
12291                            intents.get(i).toShortString(sb, false, true, false, false);
12292                            pw.println(sb.toString());
12293                            Bundle bundle = intents.get(i).getExtras();
12294                            if (bundle != null) {
12295                                pw.print("      ");
12296                                pw.println(bundle.toString());
12297                            }
12298                        }
12299                    } else {
12300                        pw.println("");
12301                    }
12302                }
12303            }
12304        }
12305
12306        if (!onlyHistory && dumpAll) {
12307            pw.println();
12308            for (BroadcastQueue queue : mBroadcastQueues) {
12309                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12310                        + queue.mBroadcastsScheduled);
12311            }
12312            pw.println("  mHandler:");
12313            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12314            needSep = true;
12315            printedAnything = true;
12316        }
12317
12318        if (!printedAnything) {
12319            pw.println("  (nothing)");
12320        }
12321    }
12322
12323    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12324            int opti, boolean dumpAll, String dumpPackage) {
12325        boolean needSep;
12326        boolean printedAnything = false;
12327
12328        ItemMatcher matcher = new ItemMatcher();
12329        matcher.build(args, opti);
12330
12331        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12332
12333        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12334        printedAnything |= needSep;
12335
12336        if (mLaunchingProviders.size() > 0) {
12337            boolean printed = false;
12338            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12339                ContentProviderRecord r = mLaunchingProviders.get(i);
12340                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12341                    continue;
12342                }
12343                if (!printed) {
12344                    if (needSep) pw.println();
12345                    needSep = true;
12346                    pw.println("  Launching content providers:");
12347                    printed = true;
12348                    printedAnything = true;
12349                }
12350                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12351                        pw.println(r);
12352            }
12353        }
12354
12355        if (mGrantedUriPermissions.size() > 0) {
12356            boolean printed = false;
12357            int dumpUid = -2;
12358            if (dumpPackage != null) {
12359                try {
12360                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12361                } catch (NameNotFoundException e) {
12362                    dumpUid = -1;
12363                }
12364            }
12365            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12366                int uid = mGrantedUriPermissions.keyAt(i);
12367                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12368                    continue;
12369                }
12370                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12371                if (!printed) {
12372                    if (needSep) pw.println();
12373                    needSep = true;
12374                    pw.println("  Granted Uri Permissions:");
12375                    printed = true;
12376                    printedAnything = true;
12377                }
12378                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12379                for (UriPermission perm : perms.values()) {
12380                    pw.print("    "); pw.println(perm);
12381                    if (dumpAll) {
12382                        perm.dump(pw, "      ");
12383                    }
12384                }
12385            }
12386        }
12387
12388        if (!printedAnything) {
12389            pw.println("  (nothing)");
12390        }
12391    }
12392
12393    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12394            int opti, boolean dumpAll, String dumpPackage) {
12395        boolean printed = false;
12396
12397        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12398
12399        if (mIntentSenderRecords.size() > 0) {
12400            Iterator<WeakReference<PendingIntentRecord>> it
12401                    = mIntentSenderRecords.values().iterator();
12402            while (it.hasNext()) {
12403                WeakReference<PendingIntentRecord> ref = it.next();
12404                PendingIntentRecord rec = ref != null ? ref.get(): null;
12405                if (dumpPackage != null && (rec == null
12406                        || !dumpPackage.equals(rec.key.packageName))) {
12407                    continue;
12408                }
12409                printed = true;
12410                if (rec != null) {
12411                    pw.print("  * "); pw.println(rec);
12412                    if (dumpAll) {
12413                        rec.dump(pw, "    ");
12414                    }
12415                } else {
12416                    pw.print("  * "); pw.println(ref);
12417                }
12418            }
12419        }
12420
12421        if (!printed) {
12422            pw.println("  (nothing)");
12423        }
12424    }
12425
12426    private static final int dumpProcessList(PrintWriter pw,
12427            ActivityManagerService service, List list,
12428            String prefix, String normalLabel, String persistentLabel,
12429            String dumpPackage) {
12430        int numPers = 0;
12431        final int N = list.size()-1;
12432        for (int i=N; i>=0; i--) {
12433            ProcessRecord r = (ProcessRecord)list.get(i);
12434            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12435                continue;
12436            }
12437            pw.println(String.format("%s%s #%2d: %s",
12438                    prefix, (r.persistent ? persistentLabel : normalLabel),
12439                    i, r.toString()));
12440            if (r.persistent) {
12441                numPers++;
12442            }
12443        }
12444        return numPers;
12445    }
12446
12447    private static final boolean dumpProcessOomList(PrintWriter pw,
12448            ActivityManagerService service, List<ProcessRecord> origList,
12449            String prefix, String normalLabel, String persistentLabel,
12450            boolean inclDetails, String dumpPackage) {
12451
12452        ArrayList<Pair<ProcessRecord, Integer>> list
12453                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12454        for (int i=0; i<origList.size(); i++) {
12455            ProcessRecord r = origList.get(i);
12456            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12457                continue;
12458            }
12459            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12460        }
12461
12462        if (list.size() <= 0) {
12463            return false;
12464        }
12465
12466        Comparator<Pair<ProcessRecord, Integer>> comparator
12467                = new Comparator<Pair<ProcessRecord, Integer>>() {
12468            @Override
12469            public int compare(Pair<ProcessRecord, Integer> object1,
12470                    Pair<ProcessRecord, Integer> object2) {
12471                if (object1.first.setAdj != object2.first.setAdj) {
12472                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12473                }
12474                if (object1.second.intValue() != object2.second.intValue()) {
12475                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12476                }
12477                return 0;
12478            }
12479        };
12480
12481        Collections.sort(list, comparator);
12482
12483        final long curRealtime = SystemClock.elapsedRealtime();
12484        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12485        final long curUptime = SystemClock.uptimeMillis();
12486        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12487
12488        for (int i=list.size()-1; i>=0; i--) {
12489            ProcessRecord r = list.get(i).first;
12490            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12491            char schedGroup;
12492            switch (r.setSchedGroup) {
12493                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12494                    schedGroup = 'B';
12495                    break;
12496                case Process.THREAD_GROUP_DEFAULT:
12497                    schedGroup = 'F';
12498                    break;
12499                default:
12500                    schedGroup = '?';
12501                    break;
12502            }
12503            char foreground;
12504            if (r.foregroundActivities) {
12505                foreground = 'A';
12506            } else if (r.foregroundServices) {
12507                foreground = 'S';
12508            } else {
12509                foreground = ' ';
12510            }
12511            String procState = ProcessList.makeProcStateString(r.curProcState);
12512            pw.print(prefix);
12513            pw.print(r.persistent ? persistentLabel : normalLabel);
12514            pw.print(" #");
12515            int num = (origList.size()-1)-list.get(i).second;
12516            if (num < 10) pw.print(' ');
12517            pw.print(num);
12518            pw.print(": ");
12519            pw.print(oomAdj);
12520            pw.print(' ');
12521            pw.print(schedGroup);
12522            pw.print('/');
12523            pw.print(foreground);
12524            pw.print('/');
12525            pw.print(procState);
12526            pw.print(" trm:");
12527            if (r.trimMemoryLevel < 10) pw.print(' ');
12528            pw.print(r.trimMemoryLevel);
12529            pw.print(' ');
12530            pw.print(r.toShortString());
12531            pw.print(" (");
12532            pw.print(r.adjType);
12533            pw.println(')');
12534            if (r.adjSource != null || r.adjTarget != null) {
12535                pw.print(prefix);
12536                pw.print("    ");
12537                if (r.adjTarget instanceof ComponentName) {
12538                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12539                } else if (r.adjTarget != null) {
12540                    pw.print(r.adjTarget.toString());
12541                } else {
12542                    pw.print("{null}");
12543                }
12544                pw.print("<=");
12545                if (r.adjSource instanceof ProcessRecord) {
12546                    pw.print("Proc{");
12547                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12548                    pw.println("}");
12549                } else if (r.adjSource != null) {
12550                    pw.println(r.adjSource.toString());
12551                } else {
12552                    pw.println("{null}");
12553                }
12554            }
12555            if (inclDetails) {
12556                pw.print(prefix);
12557                pw.print("    ");
12558                pw.print("oom: max="); pw.print(r.maxAdj);
12559                pw.print(" curRaw="); pw.print(r.curRawAdj);
12560                pw.print(" setRaw="); pw.print(r.setRawAdj);
12561                pw.print(" cur="); pw.print(r.curAdj);
12562                pw.print(" set="); pw.println(r.setAdj);
12563                pw.print(prefix);
12564                pw.print("    ");
12565                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12566                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12567                pw.print(" lastPss="); pw.print(r.lastPss);
12568                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12569                pw.print(prefix);
12570                pw.print("    ");
12571                pw.print("cached="); pw.print(r.cached);
12572                pw.print(" empty="); pw.print(r.empty);
12573                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12574
12575                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12576                    if (r.lastWakeTime != 0) {
12577                        long wtime;
12578                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12579                        synchronized (stats) {
12580                            wtime = stats.getProcessWakeTime(r.info.uid,
12581                                    r.pid, curRealtime);
12582                        }
12583                        long timeUsed = wtime - r.lastWakeTime;
12584                        pw.print(prefix);
12585                        pw.print("    ");
12586                        pw.print("keep awake over ");
12587                        TimeUtils.formatDuration(realtimeSince, pw);
12588                        pw.print(" used ");
12589                        TimeUtils.formatDuration(timeUsed, pw);
12590                        pw.print(" (");
12591                        pw.print((timeUsed*100)/realtimeSince);
12592                        pw.println("%)");
12593                    }
12594                    if (r.lastCpuTime != 0) {
12595                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12596                        pw.print(prefix);
12597                        pw.print("    ");
12598                        pw.print("run cpu over ");
12599                        TimeUtils.formatDuration(uptimeSince, pw);
12600                        pw.print(" used ");
12601                        TimeUtils.formatDuration(timeUsed, pw);
12602                        pw.print(" (");
12603                        pw.print((timeUsed*100)/uptimeSince);
12604                        pw.println("%)");
12605                    }
12606                }
12607            }
12608        }
12609        return true;
12610    }
12611
12612    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12613        ArrayList<ProcessRecord> procs;
12614        synchronized (this) {
12615            if (args != null && args.length > start
12616                    && args[start].charAt(0) != '-') {
12617                procs = new ArrayList<ProcessRecord>();
12618                int pid = -1;
12619                try {
12620                    pid = Integer.parseInt(args[start]);
12621                } catch (NumberFormatException e) {
12622                }
12623                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12624                    ProcessRecord proc = mLruProcesses.get(i);
12625                    if (proc.pid == pid) {
12626                        procs.add(proc);
12627                    } else if (proc.processName.equals(args[start])) {
12628                        procs.add(proc);
12629                    }
12630                }
12631                if (procs.size() <= 0) {
12632                    return null;
12633                }
12634            } else {
12635                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12636            }
12637        }
12638        return procs;
12639    }
12640
12641    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12642            PrintWriter pw, String[] args) {
12643        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12644        if (procs == null) {
12645            pw.println("No process found for: " + args[0]);
12646            return;
12647        }
12648
12649        long uptime = SystemClock.uptimeMillis();
12650        long realtime = SystemClock.elapsedRealtime();
12651        pw.println("Applications Graphics Acceleration Info:");
12652        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12653
12654        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12655            ProcessRecord r = procs.get(i);
12656            if (r.thread != null) {
12657                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12658                pw.flush();
12659                try {
12660                    TransferPipe tp = new TransferPipe();
12661                    try {
12662                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12663                        tp.go(fd);
12664                    } finally {
12665                        tp.kill();
12666                    }
12667                } catch (IOException e) {
12668                    pw.println("Failure while dumping the app: " + r);
12669                    pw.flush();
12670                } catch (RemoteException e) {
12671                    pw.println("Got a RemoteException while dumping the app " + r);
12672                    pw.flush();
12673                }
12674            }
12675        }
12676    }
12677
12678    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12679        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12680        if (procs == null) {
12681            pw.println("No process found for: " + args[0]);
12682            return;
12683        }
12684
12685        pw.println("Applications Database Info:");
12686
12687        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12688            ProcessRecord r = procs.get(i);
12689            if (r.thread != null) {
12690                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12691                pw.flush();
12692                try {
12693                    TransferPipe tp = new TransferPipe();
12694                    try {
12695                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12696                        tp.go(fd);
12697                    } finally {
12698                        tp.kill();
12699                    }
12700                } catch (IOException e) {
12701                    pw.println("Failure while dumping the app: " + r);
12702                    pw.flush();
12703                } catch (RemoteException e) {
12704                    pw.println("Got a RemoteException while dumping the app " + r);
12705                    pw.flush();
12706                }
12707            }
12708        }
12709    }
12710
12711    final static class MemItem {
12712        final boolean isProc;
12713        final String label;
12714        final String shortLabel;
12715        final long pss;
12716        final int id;
12717        final boolean hasActivities;
12718        ArrayList<MemItem> subitems;
12719
12720        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12721                boolean _hasActivities) {
12722            isProc = true;
12723            label = _label;
12724            shortLabel = _shortLabel;
12725            pss = _pss;
12726            id = _id;
12727            hasActivities = _hasActivities;
12728        }
12729
12730        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12731            isProc = false;
12732            label = _label;
12733            shortLabel = _shortLabel;
12734            pss = _pss;
12735            id = _id;
12736            hasActivities = false;
12737        }
12738    }
12739
12740    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12741            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12742        if (sort && !isCompact) {
12743            Collections.sort(items, new Comparator<MemItem>() {
12744                @Override
12745                public int compare(MemItem lhs, MemItem rhs) {
12746                    if (lhs.pss < rhs.pss) {
12747                        return 1;
12748                    } else if (lhs.pss > rhs.pss) {
12749                        return -1;
12750                    }
12751                    return 0;
12752                }
12753            });
12754        }
12755
12756        for (int i=0; i<items.size(); i++) {
12757            MemItem mi = items.get(i);
12758            if (!isCompact) {
12759                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12760            } else if (mi.isProc) {
12761                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12762                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12763                pw.println(mi.hasActivities ? ",a" : ",e");
12764            } else {
12765                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12766                pw.println(mi.pss);
12767            }
12768            if (mi.subitems != null) {
12769                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12770                        true, isCompact);
12771            }
12772        }
12773    }
12774
12775    // These are in KB.
12776    static final long[] DUMP_MEM_BUCKETS = new long[] {
12777        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12778        120*1024, 160*1024, 200*1024,
12779        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12780        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12781    };
12782
12783    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12784            boolean stackLike) {
12785        int start = label.lastIndexOf('.');
12786        if (start >= 0) start++;
12787        else start = 0;
12788        int end = label.length();
12789        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12790            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12791                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12792                out.append(bucket);
12793                out.append(stackLike ? "MB." : "MB ");
12794                out.append(label, start, end);
12795                return;
12796            }
12797        }
12798        out.append(memKB/1024);
12799        out.append(stackLike ? "MB." : "MB ");
12800        out.append(label, start, end);
12801    }
12802
12803    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12804            ProcessList.NATIVE_ADJ,
12805            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12806            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12807            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12808            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12809            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12810    };
12811    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12812            "Native",
12813            "System", "Persistent", "Foreground",
12814            "Visible", "Perceptible",
12815            "Heavy Weight", "Backup",
12816            "A Services", "Home",
12817            "Previous", "B Services", "Cached"
12818    };
12819    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12820            "native",
12821            "sys", "pers", "fore",
12822            "vis", "percept",
12823            "heavy", "backup",
12824            "servicea", "home",
12825            "prev", "serviceb", "cached"
12826    };
12827
12828    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12829            long realtime, boolean isCheckinRequest, boolean isCompact) {
12830        if (isCheckinRequest || isCompact) {
12831            // short checkin version
12832            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12833        } else {
12834            pw.println("Applications Memory Usage (kB):");
12835            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12836        }
12837    }
12838
12839    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12840            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12841        boolean dumpDetails = false;
12842        boolean dumpFullDetails = false;
12843        boolean dumpDalvik = false;
12844        boolean oomOnly = false;
12845        boolean isCompact = false;
12846        boolean localOnly = false;
12847
12848        int opti = 0;
12849        while (opti < args.length) {
12850            String opt = args[opti];
12851            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12852                break;
12853            }
12854            opti++;
12855            if ("-a".equals(opt)) {
12856                dumpDetails = true;
12857                dumpFullDetails = true;
12858                dumpDalvik = true;
12859            } else if ("-d".equals(opt)) {
12860                dumpDalvik = true;
12861            } else if ("-c".equals(opt)) {
12862                isCompact = true;
12863            } else if ("--oom".equals(opt)) {
12864                oomOnly = true;
12865            } else if ("--local".equals(opt)) {
12866                localOnly = true;
12867            } else if ("-h".equals(opt)) {
12868                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12869                pw.println("  -a: include all available information for each process.");
12870                pw.println("  -d: include dalvik details when dumping process details.");
12871                pw.println("  -c: dump in a compact machine-parseable representation.");
12872                pw.println("  --oom: only show processes organized by oom adj.");
12873                pw.println("  --local: only collect details locally, don't call process.");
12874                pw.println("If [process] is specified it can be the name or ");
12875                pw.println("pid of a specific process to dump.");
12876                return;
12877            } else {
12878                pw.println("Unknown argument: " + opt + "; use -h for help");
12879            }
12880        }
12881
12882        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12883        long uptime = SystemClock.uptimeMillis();
12884        long realtime = SystemClock.elapsedRealtime();
12885        final long[] tmpLong = new long[1];
12886
12887        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12888        if (procs == null) {
12889            // No Java processes.  Maybe they want to print a native process.
12890            if (args != null && args.length > opti
12891                    && args[opti].charAt(0) != '-') {
12892                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12893                        = new ArrayList<ProcessCpuTracker.Stats>();
12894                updateCpuStatsNow();
12895                int findPid = -1;
12896                try {
12897                    findPid = Integer.parseInt(args[opti]);
12898                } catch (NumberFormatException e) {
12899                }
12900                synchronized (mProcessCpuThread) {
12901                    final int N = mProcessCpuTracker.countStats();
12902                    for (int i=0; i<N; i++) {
12903                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12904                        if (st.pid == findPid || (st.baseName != null
12905                                && st.baseName.equals(args[opti]))) {
12906                            nativeProcs.add(st);
12907                        }
12908                    }
12909                }
12910                if (nativeProcs.size() > 0) {
12911                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12912                            isCompact);
12913                    Debug.MemoryInfo mi = null;
12914                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12915                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12916                        final int pid = r.pid;
12917                        if (!isCheckinRequest && dumpDetails) {
12918                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12919                        }
12920                        if (mi == null) {
12921                            mi = new Debug.MemoryInfo();
12922                        }
12923                        if (dumpDetails || (!brief && !oomOnly)) {
12924                            Debug.getMemoryInfo(pid, mi);
12925                        } else {
12926                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12927                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12928                        }
12929                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12930                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12931                        if (isCheckinRequest) {
12932                            pw.println();
12933                        }
12934                    }
12935                    return;
12936                }
12937            }
12938            pw.println("No process found for: " + args[opti]);
12939            return;
12940        }
12941
12942        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12943            dumpDetails = true;
12944        }
12945
12946        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12947
12948        String[] innerArgs = new String[args.length-opti];
12949        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12950
12951        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12952        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12953        long nativePss=0, dalvikPss=0, otherPss=0;
12954        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12955
12956        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12957        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12958                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12959
12960        long totalPss = 0;
12961        long cachedPss = 0;
12962
12963        Debug.MemoryInfo mi = null;
12964        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12965            final ProcessRecord r = procs.get(i);
12966            final IApplicationThread thread;
12967            final int pid;
12968            final int oomAdj;
12969            final boolean hasActivities;
12970            synchronized (this) {
12971                thread = r.thread;
12972                pid = r.pid;
12973                oomAdj = r.getSetAdjWithServices();
12974                hasActivities = r.activities.size() > 0;
12975            }
12976            if (thread != null) {
12977                if (!isCheckinRequest && dumpDetails) {
12978                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12979                }
12980                if (mi == null) {
12981                    mi = new Debug.MemoryInfo();
12982                }
12983                if (dumpDetails || (!brief && !oomOnly)) {
12984                    Debug.getMemoryInfo(pid, mi);
12985                } else {
12986                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12987                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12988                }
12989                if (dumpDetails) {
12990                    if (localOnly) {
12991                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12992                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12993                        if (isCheckinRequest) {
12994                            pw.println();
12995                        }
12996                    } else {
12997                        try {
12998                            pw.flush();
12999                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13000                                    dumpDalvik, innerArgs);
13001                        } catch (RemoteException e) {
13002                            if (!isCheckinRequest) {
13003                                pw.println("Got RemoteException!");
13004                                pw.flush();
13005                            }
13006                        }
13007                    }
13008                }
13009
13010                final long myTotalPss = mi.getTotalPss();
13011                final long myTotalUss = mi.getTotalUss();
13012
13013                synchronized (this) {
13014                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13015                        // Record this for posterity if the process has been stable.
13016                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13017                    }
13018                }
13019
13020                if (!isCheckinRequest && mi != null) {
13021                    totalPss += myTotalPss;
13022                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13023                            (hasActivities ? " / activities)" : ")"),
13024                            r.processName, myTotalPss, pid, hasActivities);
13025                    procMems.add(pssItem);
13026                    procMemsMap.put(pid, pssItem);
13027
13028                    nativePss += mi.nativePss;
13029                    dalvikPss += mi.dalvikPss;
13030                    otherPss += mi.otherPss;
13031                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13032                        long mem = mi.getOtherPss(j);
13033                        miscPss[j] += mem;
13034                        otherPss -= mem;
13035                    }
13036
13037                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13038                        cachedPss += myTotalPss;
13039                    }
13040
13041                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13042                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13043                                || oomIndex == (oomPss.length-1)) {
13044                            oomPss[oomIndex] += myTotalPss;
13045                            if (oomProcs[oomIndex] == null) {
13046                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13047                            }
13048                            oomProcs[oomIndex].add(pssItem);
13049                            break;
13050                        }
13051                    }
13052                }
13053            }
13054        }
13055
13056        long nativeProcTotalPss = 0;
13057
13058        if (!isCheckinRequest && procs.size() > 1) {
13059            // If we are showing aggregations, also look for native processes to
13060            // include so that our aggregations are more accurate.
13061            updateCpuStatsNow();
13062            synchronized (mProcessCpuThread) {
13063                final int N = mProcessCpuTracker.countStats();
13064                for (int i=0; i<N; i++) {
13065                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13066                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13067                        if (mi == null) {
13068                            mi = new Debug.MemoryInfo();
13069                        }
13070                        if (!brief && !oomOnly) {
13071                            Debug.getMemoryInfo(st.pid, mi);
13072                        } else {
13073                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13074                            mi.nativePrivateDirty = (int)tmpLong[0];
13075                        }
13076
13077                        final long myTotalPss = mi.getTotalPss();
13078                        totalPss += myTotalPss;
13079                        nativeProcTotalPss += myTotalPss;
13080
13081                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13082                                st.name, myTotalPss, st.pid, false);
13083                        procMems.add(pssItem);
13084
13085                        nativePss += mi.nativePss;
13086                        dalvikPss += mi.dalvikPss;
13087                        otherPss += mi.otherPss;
13088                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13089                            long mem = mi.getOtherPss(j);
13090                            miscPss[j] += mem;
13091                            otherPss -= mem;
13092                        }
13093                        oomPss[0] += myTotalPss;
13094                        if (oomProcs[0] == null) {
13095                            oomProcs[0] = new ArrayList<MemItem>();
13096                        }
13097                        oomProcs[0].add(pssItem);
13098                    }
13099                }
13100            }
13101
13102            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13103
13104            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13105            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13106            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13107            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13108                String label = Debug.MemoryInfo.getOtherLabel(j);
13109                catMems.add(new MemItem(label, label, miscPss[j], j));
13110            }
13111
13112            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13113            for (int j=0; j<oomPss.length; j++) {
13114                if (oomPss[j] != 0) {
13115                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13116                            : DUMP_MEM_OOM_LABEL[j];
13117                    MemItem item = new MemItem(label, label, oomPss[j],
13118                            DUMP_MEM_OOM_ADJ[j]);
13119                    item.subitems = oomProcs[j];
13120                    oomMems.add(item);
13121                }
13122            }
13123
13124            if (!brief && !oomOnly && !isCompact) {
13125                pw.println();
13126                pw.println("Total PSS by process:");
13127                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13128                pw.println();
13129            }
13130            if (!isCompact) {
13131                pw.println("Total PSS by OOM adjustment:");
13132            }
13133            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13134            if (!brief && !oomOnly) {
13135                PrintWriter out = categoryPw != null ? categoryPw : pw;
13136                if (!isCompact) {
13137                    out.println();
13138                    out.println("Total PSS by category:");
13139                }
13140                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13141            }
13142            if (!isCompact) {
13143                pw.println();
13144            }
13145            MemInfoReader memInfo = new MemInfoReader();
13146            memInfo.readMemInfo();
13147            if (nativeProcTotalPss > 0) {
13148                synchronized (this) {
13149                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13150                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13151                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13152                            nativeProcTotalPss);
13153                }
13154            }
13155            if (!brief) {
13156                if (!isCompact) {
13157                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13158                    pw.print(" kB (status ");
13159                    switch (mLastMemoryLevel) {
13160                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13161                            pw.println("normal)");
13162                            break;
13163                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13164                            pw.println("moderate)");
13165                            break;
13166                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13167                            pw.println("low)");
13168                            break;
13169                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13170                            pw.println("critical)");
13171                            break;
13172                        default:
13173                            pw.print(mLastMemoryLevel);
13174                            pw.println(")");
13175                            break;
13176                    }
13177                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13178                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13179                            pw.print(cachedPss); pw.print(" cached pss + ");
13180                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13181                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13182                } else {
13183                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13184                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13185                            + memInfo.getFreeSizeKb()); pw.print(",");
13186                    pw.println(totalPss - cachedPss);
13187                }
13188            }
13189            if (!isCompact) {
13190                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13191                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13192                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13193                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13194                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13195                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13196                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13197                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13198                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13199                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13200                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13201            }
13202            if (!brief) {
13203                if (memInfo.getZramTotalSizeKb() != 0) {
13204                    if (!isCompact) {
13205                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13206                                pw.print(" kB physical used for ");
13207                                pw.print(memInfo.getSwapTotalSizeKb()
13208                                        - memInfo.getSwapFreeSizeKb());
13209                                pw.print(" kB in swap (");
13210                                pw.print(memInfo.getSwapTotalSizeKb());
13211                                pw.println(" kB total swap)");
13212                    } else {
13213                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13214                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13215                                pw.println(memInfo.getSwapFreeSizeKb());
13216                    }
13217                }
13218                final int[] SINGLE_LONG_FORMAT = new int[] {
13219                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13220                };
13221                long[] longOut = new long[1];
13222                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13223                        SINGLE_LONG_FORMAT, null, longOut, null);
13224                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13225                longOut[0] = 0;
13226                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13227                        SINGLE_LONG_FORMAT, null, longOut, null);
13228                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13229                longOut[0] = 0;
13230                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13231                        SINGLE_LONG_FORMAT, null, longOut, null);
13232                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13233                longOut[0] = 0;
13234                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13235                        SINGLE_LONG_FORMAT, null, longOut, null);
13236                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13237                if (!isCompact) {
13238                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13239                        pw.print("      KSM: "); pw.print(sharing);
13240                                pw.print(" kB saved from shared ");
13241                                pw.print(shared); pw.println(" kB");
13242                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13243                                pw.print(voltile); pw.println(" kB volatile");
13244                    }
13245                    pw.print("   Tuning: ");
13246                    pw.print(ActivityManager.staticGetMemoryClass());
13247                    pw.print(" (large ");
13248                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13249                    pw.print("), oom ");
13250                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13251                    pw.print(" kB");
13252                    pw.print(", restore limit ");
13253                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13254                    pw.print(" kB");
13255                    if (ActivityManager.isLowRamDeviceStatic()) {
13256                        pw.print(" (low-ram)");
13257                    }
13258                    if (ActivityManager.isHighEndGfx()) {
13259                        pw.print(" (high-end-gfx)");
13260                    }
13261                    pw.println();
13262                } else {
13263                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13264                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13265                    pw.println(voltile);
13266                    pw.print("tuning,");
13267                    pw.print(ActivityManager.staticGetMemoryClass());
13268                    pw.print(',');
13269                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13270                    pw.print(',');
13271                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13272                    if (ActivityManager.isLowRamDeviceStatic()) {
13273                        pw.print(",low-ram");
13274                    }
13275                    if (ActivityManager.isHighEndGfx()) {
13276                        pw.print(",high-end-gfx");
13277                    }
13278                    pw.println();
13279                }
13280            }
13281        }
13282    }
13283
13284    /**
13285     * Searches array of arguments for the specified string
13286     * @param args array of argument strings
13287     * @param value value to search for
13288     * @return true if the value is contained in the array
13289     */
13290    private static boolean scanArgs(String[] args, String value) {
13291        if (args != null) {
13292            for (String arg : args) {
13293                if (value.equals(arg)) {
13294                    return true;
13295                }
13296            }
13297        }
13298        return false;
13299    }
13300
13301    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13302            ContentProviderRecord cpr, boolean always) {
13303        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13304
13305        if (!inLaunching || always) {
13306            synchronized (cpr) {
13307                cpr.launchingApp = null;
13308                cpr.notifyAll();
13309            }
13310            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13311            String names[] = cpr.info.authority.split(";");
13312            for (int j = 0; j < names.length; j++) {
13313                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13314            }
13315        }
13316
13317        for (int i=0; i<cpr.connections.size(); i++) {
13318            ContentProviderConnection conn = cpr.connections.get(i);
13319            if (conn.waiting) {
13320                // If this connection is waiting for the provider, then we don't
13321                // need to mess with its process unless we are always removing
13322                // or for some reason the provider is not currently launching.
13323                if (inLaunching && !always) {
13324                    continue;
13325                }
13326            }
13327            ProcessRecord capp = conn.client;
13328            conn.dead = true;
13329            if (conn.stableCount > 0) {
13330                if (!capp.persistent && capp.thread != null
13331                        && capp.pid != 0
13332                        && capp.pid != MY_PID) {
13333                    killUnneededProcessLocked(capp, "depends on provider "
13334                            + cpr.name.flattenToShortString()
13335                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13336                }
13337            } else if (capp.thread != null && conn.provider.provider != null) {
13338                try {
13339                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13340                } catch (RemoteException e) {
13341                }
13342                // In the protocol here, we don't expect the client to correctly
13343                // clean up this connection, we'll just remove it.
13344                cpr.connections.remove(i);
13345                conn.client.conProviders.remove(conn);
13346            }
13347        }
13348
13349        if (inLaunching && always) {
13350            mLaunchingProviders.remove(cpr);
13351        }
13352        return inLaunching;
13353    }
13354
13355    /**
13356     * Main code for cleaning up a process when it has gone away.  This is
13357     * called both as a result of the process dying, or directly when stopping
13358     * a process when running in single process mode.
13359     */
13360    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13361            boolean restarting, boolean allowRestart, int index) {
13362        if (index >= 0) {
13363            removeLruProcessLocked(app);
13364            ProcessList.remove(app.pid);
13365        }
13366
13367        mProcessesToGc.remove(app);
13368        mPendingPssProcesses.remove(app);
13369
13370        // Dismiss any open dialogs.
13371        if (app.crashDialog != null && !app.forceCrashReport) {
13372            app.crashDialog.dismiss();
13373            app.crashDialog = null;
13374        }
13375        if (app.anrDialog != null) {
13376            app.anrDialog.dismiss();
13377            app.anrDialog = null;
13378        }
13379        if (app.waitDialog != null) {
13380            app.waitDialog.dismiss();
13381            app.waitDialog = null;
13382        }
13383
13384        app.crashing = false;
13385        app.notResponding = false;
13386
13387        app.resetPackageList(mProcessStats);
13388        app.unlinkDeathRecipient();
13389        app.makeInactive(mProcessStats);
13390        app.waitingToKill = null;
13391        app.forcingToForeground = null;
13392        updateProcessForegroundLocked(app, false, false);
13393        app.foregroundActivities = false;
13394        app.hasShownUi = false;
13395        app.treatLikeActivity = false;
13396        app.hasAboveClient = false;
13397        app.hasClientActivities = false;
13398
13399        mServices.killServicesLocked(app, allowRestart);
13400
13401        boolean restart = false;
13402
13403        // Remove published content providers.
13404        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13405            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13406            final boolean always = app.bad || !allowRestart;
13407            if (removeDyingProviderLocked(app, cpr, always) || always) {
13408                // We left the provider in the launching list, need to
13409                // restart it.
13410                restart = true;
13411            }
13412
13413            cpr.provider = null;
13414            cpr.proc = null;
13415        }
13416        app.pubProviders.clear();
13417
13418        // Take care of any launching providers waiting for this process.
13419        if (checkAppInLaunchingProvidersLocked(app, false)) {
13420            restart = true;
13421        }
13422
13423        // Unregister from connected content providers.
13424        if (!app.conProviders.isEmpty()) {
13425            for (int i=0; i<app.conProviders.size(); i++) {
13426                ContentProviderConnection conn = app.conProviders.get(i);
13427                conn.provider.connections.remove(conn);
13428            }
13429            app.conProviders.clear();
13430        }
13431
13432        // At this point there may be remaining entries in mLaunchingProviders
13433        // where we were the only one waiting, so they are no longer of use.
13434        // Look for these and clean up if found.
13435        // XXX Commented out for now.  Trying to figure out a way to reproduce
13436        // the actual situation to identify what is actually going on.
13437        if (false) {
13438            for (int i=0; i<mLaunchingProviders.size(); i++) {
13439                ContentProviderRecord cpr = (ContentProviderRecord)
13440                        mLaunchingProviders.get(i);
13441                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13442                    synchronized (cpr) {
13443                        cpr.launchingApp = null;
13444                        cpr.notifyAll();
13445                    }
13446                }
13447            }
13448        }
13449
13450        skipCurrentReceiverLocked(app);
13451
13452        // Unregister any receivers.
13453        for (int i=app.receivers.size()-1; i>=0; i--) {
13454            removeReceiverLocked(app.receivers.valueAt(i));
13455        }
13456        app.receivers.clear();
13457
13458        // If the app is undergoing backup, tell the backup manager about it
13459        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13460            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13461                    + mBackupTarget.appInfo + " died during backup");
13462            try {
13463                IBackupManager bm = IBackupManager.Stub.asInterface(
13464                        ServiceManager.getService(Context.BACKUP_SERVICE));
13465                bm.agentDisconnected(app.info.packageName);
13466            } catch (RemoteException e) {
13467                // can't happen; backup manager is local
13468            }
13469        }
13470
13471        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13472            ProcessChangeItem item = mPendingProcessChanges.get(i);
13473            if (item.pid == app.pid) {
13474                mPendingProcessChanges.remove(i);
13475                mAvailProcessChanges.add(item);
13476            }
13477        }
13478        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13479
13480        // If the caller is restarting this app, then leave it in its
13481        // current lists and let the caller take care of it.
13482        if (restarting) {
13483            return;
13484        }
13485
13486        if (!app.persistent || app.isolated) {
13487            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13488                    "Removing non-persistent process during cleanup: " + app);
13489            mProcessNames.remove(app.processName, app.uid);
13490            mIsolatedProcesses.remove(app.uid);
13491            if (mHeavyWeightProcess == app) {
13492                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13493                        mHeavyWeightProcess.userId, 0));
13494                mHeavyWeightProcess = null;
13495            }
13496        } else if (!app.removed) {
13497            // This app is persistent, so we need to keep its record around.
13498            // If it is not already on the pending app list, add it there
13499            // and start a new process for it.
13500            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13501                mPersistentStartingProcesses.add(app);
13502                restart = true;
13503            }
13504        }
13505        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13506                "Clean-up removing on hold: " + app);
13507        mProcessesOnHold.remove(app);
13508
13509        if (app == mHomeProcess) {
13510            mHomeProcess = null;
13511        }
13512        if (app == mPreviousProcess) {
13513            mPreviousProcess = null;
13514        }
13515
13516        if (restart && !app.isolated) {
13517            // We have components that still need to be running in the
13518            // process, so re-launch it.
13519            mProcessNames.put(app.processName, app.uid, app);
13520            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13521        } else if (app.pid > 0 && app.pid != MY_PID) {
13522            // Goodbye!
13523            boolean removed;
13524            synchronized (mPidsSelfLocked) {
13525                mPidsSelfLocked.remove(app.pid);
13526                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13527            }
13528            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13529            if (app.isolated) {
13530                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13531            }
13532            app.setPid(0);
13533        }
13534    }
13535
13536    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13537        // Look through the content providers we are waiting to have launched,
13538        // and if any run in this process then either schedule a restart of
13539        // the process or kill the client waiting for it if this process has
13540        // gone bad.
13541        int NL = mLaunchingProviders.size();
13542        boolean restart = false;
13543        for (int i=0; i<NL; i++) {
13544            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13545            if (cpr.launchingApp == app) {
13546                if (!alwaysBad && !app.bad) {
13547                    restart = true;
13548                } else {
13549                    removeDyingProviderLocked(app, cpr, true);
13550                    // cpr should have been removed from mLaunchingProviders
13551                    NL = mLaunchingProviders.size();
13552                    i--;
13553                }
13554            }
13555        }
13556        return restart;
13557    }
13558
13559    // =========================================================
13560    // SERVICES
13561    // =========================================================
13562
13563    @Override
13564    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13565            int flags) {
13566        enforceNotIsolatedCaller("getServices");
13567        synchronized (this) {
13568            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13569        }
13570    }
13571
13572    @Override
13573    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13574        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13575        synchronized (this) {
13576            return mServices.getRunningServiceControlPanelLocked(name);
13577        }
13578    }
13579
13580    @Override
13581    public ComponentName startService(IApplicationThread caller, Intent service,
13582            String resolvedType, int userId) {
13583        enforceNotIsolatedCaller("startService");
13584        // Refuse possible leaked file descriptors
13585        if (service != null && service.hasFileDescriptors() == true) {
13586            throw new IllegalArgumentException("File descriptors passed in Intent");
13587        }
13588
13589        if (DEBUG_SERVICE)
13590            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13591        synchronized(this) {
13592            final int callingPid = Binder.getCallingPid();
13593            final int callingUid = Binder.getCallingUid();
13594            final long origId = Binder.clearCallingIdentity();
13595            ComponentName res = mServices.startServiceLocked(caller, service,
13596                    resolvedType, callingPid, callingUid, userId);
13597            Binder.restoreCallingIdentity(origId);
13598            return res;
13599        }
13600    }
13601
13602    ComponentName startServiceInPackage(int uid,
13603            Intent service, String resolvedType, int userId) {
13604        synchronized(this) {
13605            if (DEBUG_SERVICE)
13606                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13607            final long origId = Binder.clearCallingIdentity();
13608            ComponentName res = mServices.startServiceLocked(null, service,
13609                    resolvedType, -1, uid, userId);
13610            Binder.restoreCallingIdentity(origId);
13611            return res;
13612        }
13613    }
13614
13615    @Override
13616    public int stopService(IApplicationThread caller, Intent service,
13617            String resolvedType, int userId) {
13618        enforceNotIsolatedCaller("stopService");
13619        // Refuse possible leaked file descriptors
13620        if (service != null && service.hasFileDescriptors() == true) {
13621            throw new IllegalArgumentException("File descriptors passed in Intent");
13622        }
13623
13624        synchronized(this) {
13625            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13626        }
13627    }
13628
13629    @Override
13630    public IBinder peekService(Intent service, String resolvedType) {
13631        enforceNotIsolatedCaller("peekService");
13632        // Refuse possible leaked file descriptors
13633        if (service != null && service.hasFileDescriptors() == true) {
13634            throw new IllegalArgumentException("File descriptors passed in Intent");
13635        }
13636        synchronized(this) {
13637            return mServices.peekServiceLocked(service, resolvedType);
13638        }
13639    }
13640
13641    @Override
13642    public boolean stopServiceToken(ComponentName className, IBinder token,
13643            int startId) {
13644        synchronized(this) {
13645            return mServices.stopServiceTokenLocked(className, token, startId);
13646        }
13647    }
13648
13649    @Override
13650    public void setServiceForeground(ComponentName className, IBinder token,
13651            int id, Notification notification, boolean removeNotification) {
13652        synchronized(this) {
13653            mServices.setServiceForegroundLocked(className, token, id, notification,
13654                    removeNotification);
13655        }
13656    }
13657
13658    @Override
13659    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13660            boolean requireFull, String name, String callerPackage) {
13661        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13662                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13663    }
13664
13665    int unsafeConvertIncomingUser(int userId) {
13666        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13667                ? mCurrentUserId : userId;
13668    }
13669
13670    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13671            int allowMode, String name, String callerPackage) {
13672        final int callingUserId = UserHandle.getUserId(callingUid);
13673        if (callingUserId == userId) {
13674            return userId;
13675        }
13676
13677        // Note that we may be accessing mCurrentUserId outside of a lock...
13678        // shouldn't be a big deal, if this is being called outside
13679        // of a locked context there is intrinsically a race with
13680        // the value the caller will receive and someone else changing it.
13681        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13682        // we will switch to the calling user if access to the current user fails.
13683        int targetUserId = unsafeConvertIncomingUser(userId);
13684
13685        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13686            final boolean allow;
13687            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13688                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13689                // If the caller has this permission, they always pass go.  And collect $200.
13690                allow = true;
13691            } else if (allowMode == ALLOW_FULL_ONLY) {
13692                // We require full access, sucks to be you.
13693                allow = false;
13694            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13695                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13696                // If the caller does not have either permission, they are always doomed.
13697                allow = false;
13698            } else if (allowMode == ALLOW_NON_FULL) {
13699                // We are blanket allowing non-full access, you lucky caller!
13700                allow = true;
13701            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13702                // We may or may not allow this depending on whether the two users are
13703                // in the same profile.
13704                synchronized (mUserProfileGroupIdsSelfLocked) {
13705                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13706                            UserInfo.NO_PROFILE_GROUP_ID);
13707                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13708                            UserInfo.NO_PROFILE_GROUP_ID);
13709                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13710                            && callingProfile == targetProfile;
13711                }
13712            } else {
13713                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13714            }
13715            if (!allow) {
13716                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13717                    // In this case, they would like to just execute as their
13718                    // owner user instead of failing.
13719                    targetUserId = callingUserId;
13720                } else {
13721                    StringBuilder builder = new StringBuilder(128);
13722                    builder.append("Permission Denial: ");
13723                    builder.append(name);
13724                    if (callerPackage != null) {
13725                        builder.append(" from ");
13726                        builder.append(callerPackage);
13727                    }
13728                    builder.append(" asks to run as user ");
13729                    builder.append(userId);
13730                    builder.append(" but is calling from user ");
13731                    builder.append(UserHandle.getUserId(callingUid));
13732                    builder.append("; this requires ");
13733                    builder.append(INTERACT_ACROSS_USERS_FULL);
13734                    if (allowMode != ALLOW_FULL_ONLY) {
13735                        builder.append(" or ");
13736                        builder.append(INTERACT_ACROSS_USERS);
13737                    }
13738                    String msg = builder.toString();
13739                    Slog.w(TAG, msg);
13740                    throw new SecurityException(msg);
13741                }
13742            }
13743        }
13744        if (!allowAll && targetUserId < 0) {
13745            throw new IllegalArgumentException(
13746                    "Call does not support special user #" + targetUserId);
13747        }
13748        return targetUserId;
13749    }
13750
13751    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13752            String className, int flags) {
13753        boolean result = false;
13754        // For apps that don't have pre-defined UIDs, check for permission
13755        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13756            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13757                if (ActivityManager.checkUidPermission(
13758                        INTERACT_ACROSS_USERS,
13759                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13760                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13761                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13762                            + " requests FLAG_SINGLE_USER, but app does not hold "
13763                            + INTERACT_ACROSS_USERS;
13764                    Slog.w(TAG, msg);
13765                    throw new SecurityException(msg);
13766                }
13767                // Permission passed
13768                result = true;
13769            }
13770        } else if ("system".equals(componentProcessName)) {
13771            result = true;
13772        } else {
13773            // App with pre-defined UID, check if it's a persistent app
13774            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13775        }
13776        if (DEBUG_MU) {
13777            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13778                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13779        }
13780        return result;
13781    }
13782
13783    /**
13784     * Checks to see if the caller is in the same app as the singleton
13785     * component, or the component is in a special app. It allows special apps
13786     * to export singleton components but prevents exporting singleton
13787     * components for regular apps.
13788     */
13789    boolean isValidSingletonCall(int callingUid, int componentUid) {
13790        int componentAppId = UserHandle.getAppId(componentUid);
13791        return UserHandle.isSameApp(callingUid, componentUid)
13792                || componentAppId == Process.SYSTEM_UID
13793                || componentAppId == Process.PHONE_UID
13794                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13795                        == PackageManager.PERMISSION_GRANTED;
13796    }
13797
13798    public int bindService(IApplicationThread caller, IBinder token,
13799            Intent service, String resolvedType,
13800            IServiceConnection connection, int flags, int userId) {
13801        enforceNotIsolatedCaller("bindService");
13802        // Refuse possible leaked file descriptors
13803        if (service != null && service.hasFileDescriptors() == true) {
13804            throw new IllegalArgumentException("File descriptors passed in Intent");
13805        }
13806
13807        synchronized(this) {
13808            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13809                    connection, flags, userId);
13810        }
13811    }
13812
13813    public boolean unbindService(IServiceConnection connection) {
13814        synchronized (this) {
13815            return mServices.unbindServiceLocked(connection);
13816        }
13817    }
13818
13819    public void publishService(IBinder token, Intent intent, IBinder service) {
13820        // Refuse possible leaked file descriptors
13821        if (intent != null && intent.hasFileDescriptors() == true) {
13822            throw new IllegalArgumentException("File descriptors passed in Intent");
13823        }
13824
13825        synchronized(this) {
13826            if (!(token instanceof ServiceRecord)) {
13827                throw new IllegalArgumentException("Invalid service token");
13828            }
13829            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13830        }
13831    }
13832
13833    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13834        // Refuse possible leaked file descriptors
13835        if (intent != null && intent.hasFileDescriptors() == true) {
13836            throw new IllegalArgumentException("File descriptors passed in Intent");
13837        }
13838
13839        synchronized(this) {
13840            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13841        }
13842    }
13843
13844    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13845        synchronized(this) {
13846            if (!(token instanceof ServiceRecord)) {
13847                throw new IllegalArgumentException("Invalid service token");
13848            }
13849            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13850        }
13851    }
13852
13853    // =========================================================
13854    // BACKUP AND RESTORE
13855    // =========================================================
13856
13857    // Cause the target app to be launched if necessary and its backup agent
13858    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13859    // activity manager to announce its creation.
13860    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13861        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13862        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13863
13864        synchronized(this) {
13865            // !!! TODO: currently no check here that we're already bound
13866            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13867            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13868            synchronized (stats) {
13869                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13870            }
13871
13872            // Backup agent is now in use, its package can't be stopped.
13873            try {
13874                AppGlobals.getPackageManager().setPackageStoppedState(
13875                        app.packageName, false, UserHandle.getUserId(app.uid));
13876            } catch (RemoteException e) {
13877            } catch (IllegalArgumentException e) {
13878                Slog.w(TAG, "Failed trying to unstop package "
13879                        + app.packageName + ": " + e);
13880            }
13881
13882            BackupRecord r = new BackupRecord(ss, app, backupMode);
13883            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13884                    ? new ComponentName(app.packageName, app.backupAgentName)
13885                    : new ComponentName("android", "FullBackupAgent");
13886            // startProcessLocked() returns existing proc's record if it's already running
13887            ProcessRecord proc = startProcessLocked(app.processName, app,
13888                    false, 0, "backup", hostingName, false, false, false);
13889            if (proc == null) {
13890                Slog.e(TAG, "Unable to start backup agent process " + r);
13891                return false;
13892            }
13893
13894            r.app = proc;
13895            mBackupTarget = r;
13896            mBackupAppName = app.packageName;
13897
13898            // Try not to kill the process during backup
13899            updateOomAdjLocked(proc);
13900
13901            // If the process is already attached, schedule the creation of the backup agent now.
13902            // If it is not yet live, this will be done when it attaches to the framework.
13903            if (proc.thread != null) {
13904                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13905                try {
13906                    proc.thread.scheduleCreateBackupAgent(app,
13907                            compatibilityInfoForPackageLocked(app), backupMode);
13908                } catch (RemoteException e) {
13909                    // Will time out on the backup manager side
13910                }
13911            } else {
13912                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13913            }
13914            // Invariants: at this point, the target app process exists and the application
13915            // is either already running or in the process of coming up.  mBackupTarget and
13916            // mBackupAppName describe the app, so that when it binds back to the AM we
13917            // know that it's scheduled for a backup-agent operation.
13918        }
13919
13920        return true;
13921    }
13922
13923    @Override
13924    public void clearPendingBackup() {
13925        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13926        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13927
13928        synchronized (this) {
13929            mBackupTarget = null;
13930            mBackupAppName = null;
13931        }
13932    }
13933
13934    // A backup agent has just come up
13935    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13936        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13937                + " = " + agent);
13938
13939        synchronized(this) {
13940            if (!agentPackageName.equals(mBackupAppName)) {
13941                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13942                return;
13943            }
13944        }
13945
13946        long oldIdent = Binder.clearCallingIdentity();
13947        try {
13948            IBackupManager bm = IBackupManager.Stub.asInterface(
13949                    ServiceManager.getService(Context.BACKUP_SERVICE));
13950            bm.agentConnected(agentPackageName, agent);
13951        } catch (RemoteException e) {
13952            // can't happen; the backup manager service is local
13953        } catch (Exception e) {
13954            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13955            e.printStackTrace();
13956        } finally {
13957            Binder.restoreCallingIdentity(oldIdent);
13958        }
13959    }
13960
13961    // done with this agent
13962    public void unbindBackupAgent(ApplicationInfo appInfo) {
13963        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13964        if (appInfo == null) {
13965            Slog.w(TAG, "unbind backup agent for null app");
13966            return;
13967        }
13968
13969        synchronized(this) {
13970            try {
13971                if (mBackupAppName == null) {
13972                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13973                    return;
13974                }
13975
13976                if (!mBackupAppName.equals(appInfo.packageName)) {
13977                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13978                    return;
13979                }
13980
13981                // Not backing this app up any more; reset its OOM adjustment
13982                final ProcessRecord proc = mBackupTarget.app;
13983                updateOomAdjLocked(proc);
13984
13985                // If the app crashed during backup, 'thread' will be null here
13986                if (proc.thread != null) {
13987                    try {
13988                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13989                                compatibilityInfoForPackageLocked(appInfo));
13990                    } catch (Exception e) {
13991                        Slog.e(TAG, "Exception when unbinding backup agent:");
13992                        e.printStackTrace();
13993                    }
13994                }
13995            } finally {
13996                mBackupTarget = null;
13997                mBackupAppName = null;
13998            }
13999        }
14000    }
14001    // =========================================================
14002    // BROADCASTS
14003    // =========================================================
14004
14005    private final List getStickiesLocked(String action, IntentFilter filter,
14006            List cur, int userId) {
14007        final ContentResolver resolver = mContext.getContentResolver();
14008        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14009        if (stickies == null) {
14010            return cur;
14011        }
14012        final ArrayList<Intent> list = stickies.get(action);
14013        if (list == null) {
14014            return cur;
14015        }
14016        int N = list.size();
14017        for (int i=0; i<N; i++) {
14018            Intent intent = list.get(i);
14019            if (filter.match(resolver, intent, true, TAG) >= 0) {
14020                if (cur == null) {
14021                    cur = new ArrayList<Intent>();
14022                }
14023                cur.add(intent);
14024            }
14025        }
14026        return cur;
14027    }
14028
14029    boolean isPendingBroadcastProcessLocked(int pid) {
14030        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14031                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14032    }
14033
14034    void skipPendingBroadcastLocked(int pid) {
14035            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14036            for (BroadcastQueue queue : mBroadcastQueues) {
14037                queue.skipPendingBroadcastLocked(pid);
14038            }
14039    }
14040
14041    // The app just attached; send any pending broadcasts that it should receive
14042    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14043        boolean didSomething = false;
14044        for (BroadcastQueue queue : mBroadcastQueues) {
14045            didSomething |= queue.sendPendingBroadcastsLocked(app);
14046        }
14047        return didSomething;
14048    }
14049
14050    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14051            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14052        enforceNotIsolatedCaller("registerReceiver");
14053        int callingUid;
14054        int callingPid;
14055        synchronized(this) {
14056            ProcessRecord callerApp = null;
14057            if (caller != null) {
14058                callerApp = getRecordForAppLocked(caller);
14059                if (callerApp == null) {
14060                    throw new SecurityException(
14061                            "Unable to find app for caller " + caller
14062                            + " (pid=" + Binder.getCallingPid()
14063                            + ") when registering receiver " + receiver);
14064                }
14065                if (callerApp.info.uid != Process.SYSTEM_UID &&
14066                        !callerApp.pkgList.containsKey(callerPackage) &&
14067                        !"android".equals(callerPackage)) {
14068                    throw new SecurityException("Given caller package " + callerPackage
14069                            + " is not running in process " + callerApp);
14070                }
14071                callingUid = callerApp.info.uid;
14072                callingPid = callerApp.pid;
14073            } else {
14074                callerPackage = null;
14075                callingUid = Binder.getCallingUid();
14076                callingPid = Binder.getCallingPid();
14077            }
14078
14079            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14080                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14081
14082            List allSticky = null;
14083
14084            // Look for any matching sticky broadcasts...
14085            Iterator actions = filter.actionsIterator();
14086            if (actions != null) {
14087                while (actions.hasNext()) {
14088                    String action = (String)actions.next();
14089                    allSticky = getStickiesLocked(action, filter, allSticky,
14090                            UserHandle.USER_ALL);
14091                    allSticky = getStickiesLocked(action, filter, allSticky,
14092                            UserHandle.getUserId(callingUid));
14093                }
14094            } else {
14095                allSticky = getStickiesLocked(null, filter, allSticky,
14096                        UserHandle.USER_ALL);
14097                allSticky = getStickiesLocked(null, filter, allSticky,
14098                        UserHandle.getUserId(callingUid));
14099            }
14100
14101            // The first sticky in the list is returned directly back to
14102            // the client.
14103            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14104
14105            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14106                    + ": " + sticky);
14107
14108            if (receiver == null) {
14109                return sticky;
14110            }
14111
14112            ReceiverList rl
14113                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14114            if (rl == null) {
14115                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14116                        userId, receiver);
14117                if (rl.app != null) {
14118                    rl.app.receivers.add(rl);
14119                } else {
14120                    try {
14121                        receiver.asBinder().linkToDeath(rl, 0);
14122                    } catch (RemoteException e) {
14123                        return sticky;
14124                    }
14125                    rl.linkedToDeath = true;
14126                }
14127                mRegisteredReceivers.put(receiver.asBinder(), rl);
14128            } else if (rl.uid != callingUid) {
14129                throw new IllegalArgumentException(
14130                        "Receiver requested to register for uid " + callingUid
14131                        + " was previously registered for uid " + rl.uid);
14132            } else if (rl.pid != callingPid) {
14133                throw new IllegalArgumentException(
14134                        "Receiver requested to register for pid " + callingPid
14135                        + " was previously registered for pid " + rl.pid);
14136            } else if (rl.userId != userId) {
14137                throw new IllegalArgumentException(
14138                        "Receiver requested to register for user " + userId
14139                        + " was previously registered for user " + rl.userId);
14140            }
14141            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14142                    permission, callingUid, userId);
14143            rl.add(bf);
14144            if (!bf.debugCheck()) {
14145                Slog.w(TAG, "==> For Dynamic broadast");
14146            }
14147            mReceiverResolver.addFilter(bf);
14148
14149            // Enqueue broadcasts for all existing stickies that match
14150            // this filter.
14151            if (allSticky != null) {
14152                ArrayList receivers = new ArrayList();
14153                receivers.add(bf);
14154
14155                int N = allSticky.size();
14156                for (int i=0; i<N; i++) {
14157                    Intent intent = (Intent)allSticky.get(i);
14158                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14159                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14160                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14161                            null, null, false, true, true, -1);
14162                    queue.enqueueParallelBroadcastLocked(r);
14163                    queue.scheduleBroadcastsLocked();
14164                }
14165            }
14166
14167            return sticky;
14168        }
14169    }
14170
14171    public void unregisterReceiver(IIntentReceiver receiver) {
14172        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14173
14174        final long origId = Binder.clearCallingIdentity();
14175        try {
14176            boolean doTrim = false;
14177
14178            synchronized(this) {
14179                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14180                if (rl != null) {
14181                    if (rl.curBroadcast != null) {
14182                        BroadcastRecord r = rl.curBroadcast;
14183                        final boolean doNext = finishReceiverLocked(
14184                                receiver.asBinder(), r.resultCode, r.resultData,
14185                                r.resultExtras, r.resultAbort);
14186                        if (doNext) {
14187                            doTrim = true;
14188                            r.queue.processNextBroadcast(false);
14189                        }
14190                    }
14191
14192                    if (rl.app != null) {
14193                        rl.app.receivers.remove(rl);
14194                    }
14195                    removeReceiverLocked(rl);
14196                    if (rl.linkedToDeath) {
14197                        rl.linkedToDeath = false;
14198                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14199                    }
14200                }
14201            }
14202
14203            // If we actually concluded any broadcasts, we might now be able
14204            // to trim the recipients' apps from our working set
14205            if (doTrim) {
14206                trimApplications();
14207                return;
14208            }
14209
14210        } finally {
14211            Binder.restoreCallingIdentity(origId);
14212        }
14213    }
14214
14215    void removeReceiverLocked(ReceiverList rl) {
14216        mRegisteredReceivers.remove(rl.receiver.asBinder());
14217        int N = rl.size();
14218        for (int i=0; i<N; i++) {
14219            mReceiverResolver.removeFilter(rl.get(i));
14220        }
14221    }
14222
14223    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14224        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14225            ProcessRecord r = mLruProcesses.get(i);
14226            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14227                try {
14228                    r.thread.dispatchPackageBroadcast(cmd, packages);
14229                } catch (RemoteException ex) {
14230                }
14231            }
14232        }
14233    }
14234
14235    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14236            int[] users) {
14237        List<ResolveInfo> receivers = null;
14238        try {
14239            HashSet<ComponentName> singleUserReceivers = null;
14240            boolean scannedFirstReceivers = false;
14241            for (int user : users) {
14242                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14243                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14244                if (user != 0 && newReceivers != null) {
14245                    // If this is not the primary user, we need to check for
14246                    // any receivers that should be filtered out.
14247                    for (int i=0; i<newReceivers.size(); i++) {
14248                        ResolveInfo ri = newReceivers.get(i);
14249                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14250                            newReceivers.remove(i);
14251                            i--;
14252                        }
14253                    }
14254                }
14255                if (newReceivers != null && newReceivers.size() == 0) {
14256                    newReceivers = null;
14257                }
14258                if (receivers == null) {
14259                    receivers = newReceivers;
14260                } else if (newReceivers != null) {
14261                    // We need to concatenate the additional receivers
14262                    // found with what we have do far.  This would be easy,
14263                    // but we also need to de-dup any receivers that are
14264                    // singleUser.
14265                    if (!scannedFirstReceivers) {
14266                        // Collect any single user receivers we had already retrieved.
14267                        scannedFirstReceivers = true;
14268                        for (int i=0; i<receivers.size(); i++) {
14269                            ResolveInfo ri = receivers.get(i);
14270                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14271                                ComponentName cn = new ComponentName(
14272                                        ri.activityInfo.packageName, ri.activityInfo.name);
14273                                if (singleUserReceivers == null) {
14274                                    singleUserReceivers = new HashSet<ComponentName>();
14275                                }
14276                                singleUserReceivers.add(cn);
14277                            }
14278                        }
14279                    }
14280                    // Add the new results to the existing results, tracking
14281                    // and de-dupping single user receivers.
14282                    for (int i=0; i<newReceivers.size(); i++) {
14283                        ResolveInfo ri = newReceivers.get(i);
14284                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14285                            ComponentName cn = new ComponentName(
14286                                    ri.activityInfo.packageName, ri.activityInfo.name);
14287                            if (singleUserReceivers == null) {
14288                                singleUserReceivers = new HashSet<ComponentName>();
14289                            }
14290                            if (!singleUserReceivers.contains(cn)) {
14291                                singleUserReceivers.add(cn);
14292                                receivers.add(ri);
14293                            }
14294                        } else {
14295                            receivers.add(ri);
14296                        }
14297                    }
14298                }
14299            }
14300        } catch (RemoteException ex) {
14301            // pm is in same process, this will never happen.
14302        }
14303        return receivers;
14304    }
14305
14306    private final int broadcastIntentLocked(ProcessRecord callerApp,
14307            String callerPackage, Intent intent, String resolvedType,
14308            IIntentReceiver resultTo, int resultCode, String resultData,
14309            Bundle map, String requiredPermission, int appOp,
14310            boolean ordered, boolean sticky, int callingPid, int callingUid,
14311            int userId) {
14312        intent = new Intent(intent);
14313
14314        // By default broadcasts do not go to stopped apps.
14315        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14316
14317        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14318            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14319            + " ordered=" + ordered + " userid=" + userId);
14320        if ((resultTo != null) && !ordered) {
14321            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14322        }
14323
14324        userId = handleIncomingUser(callingPid, callingUid, userId,
14325                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14326
14327        // Make sure that the user who is receiving this broadcast is started.
14328        // If not, we will just skip it.
14329
14330
14331        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14332            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14333                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14334                Slog.w(TAG, "Skipping broadcast of " + intent
14335                        + ": user " + userId + " is stopped");
14336                return ActivityManager.BROADCAST_SUCCESS;
14337            }
14338        }
14339
14340        /*
14341         * Prevent non-system code (defined here to be non-persistent
14342         * processes) from sending protected broadcasts.
14343         */
14344        int callingAppId = UserHandle.getAppId(callingUid);
14345        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14346            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14347            || callingAppId == Process.NFC_UID || callingUid == 0) {
14348            // Always okay.
14349        } else if (callerApp == null || !callerApp.persistent) {
14350            try {
14351                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14352                        intent.getAction())) {
14353                    String msg = "Permission Denial: not allowed to send broadcast "
14354                            + intent.getAction() + " from pid="
14355                            + callingPid + ", uid=" + callingUid;
14356                    Slog.w(TAG, msg);
14357                    throw new SecurityException(msg);
14358                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14359                    // Special case for compatibility: we don't want apps to send this,
14360                    // but historically it has not been protected and apps may be using it
14361                    // to poke their own app widget.  So, instead of making it protected,
14362                    // just limit it to the caller.
14363                    if (callerApp == null) {
14364                        String msg = "Permission Denial: not allowed to send broadcast "
14365                                + intent.getAction() + " from unknown caller.";
14366                        Slog.w(TAG, msg);
14367                        throw new SecurityException(msg);
14368                    } else if (intent.getComponent() != null) {
14369                        // They are good enough to send to an explicit component...  verify
14370                        // it is being sent to the calling app.
14371                        if (!intent.getComponent().getPackageName().equals(
14372                                callerApp.info.packageName)) {
14373                            String msg = "Permission Denial: not allowed to send broadcast "
14374                                    + intent.getAction() + " to "
14375                                    + intent.getComponent().getPackageName() + " from "
14376                                    + callerApp.info.packageName;
14377                            Slog.w(TAG, msg);
14378                            throw new SecurityException(msg);
14379                        }
14380                    } else {
14381                        // Limit broadcast to their own package.
14382                        intent.setPackage(callerApp.info.packageName);
14383                    }
14384                }
14385            } catch (RemoteException e) {
14386                Slog.w(TAG, "Remote exception", e);
14387                return ActivityManager.BROADCAST_SUCCESS;
14388            }
14389        }
14390
14391        // Handle special intents: if this broadcast is from the package
14392        // manager about a package being removed, we need to remove all of
14393        // its activities from the history stack.
14394        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14395                intent.getAction());
14396        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14397                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14398                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14399                || uidRemoved) {
14400            if (checkComponentPermission(
14401                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14402                    callingPid, callingUid, -1, true)
14403                    == PackageManager.PERMISSION_GRANTED) {
14404                if (uidRemoved) {
14405                    final Bundle intentExtras = intent.getExtras();
14406                    final int uid = intentExtras != null
14407                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14408                    if (uid >= 0) {
14409                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14410                        synchronized (bs) {
14411                            bs.removeUidStatsLocked(uid);
14412                        }
14413                        mAppOpsService.uidRemoved(uid);
14414                    }
14415                } else {
14416                    // If resources are unavailable just force stop all
14417                    // those packages and flush the attribute cache as well.
14418                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14419                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14420                        if (list != null && (list.length > 0)) {
14421                            for (String pkg : list) {
14422                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14423                                        "storage unmount");
14424                            }
14425                            sendPackageBroadcastLocked(
14426                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14427                        }
14428                    } else {
14429                        Uri data = intent.getData();
14430                        String ssp;
14431                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14432                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14433                                    intent.getAction());
14434                            boolean fullUninstall = removed &&
14435                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14436                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14437                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14438                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14439                                        false, fullUninstall, userId,
14440                                        removed ? "pkg removed" : "pkg changed");
14441                            }
14442                            if (removed) {
14443                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14444                                        new String[] {ssp}, userId);
14445                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14446                                    mAppOpsService.packageRemoved(
14447                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14448
14449                                    // Remove all permissions granted from/to this package
14450                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14451                                }
14452                            }
14453                        }
14454                    }
14455                }
14456            } else {
14457                String msg = "Permission Denial: " + intent.getAction()
14458                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14459                        + ", uid=" + callingUid + ")"
14460                        + " requires "
14461                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14462                Slog.w(TAG, msg);
14463                throw new SecurityException(msg);
14464            }
14465
14466        // Special case for adding a package: by default turn on compatibility
14467        // mode.
14468        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14469            Uri data = intent.getData();
14470            String ssp;
14471            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14472                mCompatModePackages.handlePackageAddedLocked(ssp,
14473                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14474            }
14475        }
14476
14477        /*
14478         * If this is the time zone changed action, queue up a message that will reset the timezone
14479         * of all currently running processes. This message will get queued up before the broadcast
14480         * happens.
14481         */
14482        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14483            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14484        }
14485
14486        /*
14487         * If the user set the time, let all running processes know.
14488         */
14489        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14490            final int is24Hour = intent.getBooleanExtra(
14491                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14492            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14493        }
14494
14495        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14496            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14497        }
14498
14499        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14500            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14501            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14502        }
14503
14504        // Add to the sticky list if requested.
14505        if (sticky) {
14506            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14507                    callingPid, callingUid)
14508                    != PackageManager.PERMISSION_GRANTED) {
14509                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14510                        + callingPid + ", uid=" + callingUid
14511                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14512                Slog.w(TAG, msg);
14513                throw new SecurityException(msg);
14514            }
14515            if (requiredPermission != null) {
14516                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14517                        + " and enforce permission " + requiredPermission);
14518                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14519            }
14520            if (intent.getComponent() != null) {
14521                throw new SecurityException(
14522                        "Sticky broadcasts can't target a specific component");
14523            }
14524            // We use userId directly here, since the "all" target is maintained
14525            // as a separate set of sticky broadcasts.
14526            if (userId != UserHandle.USER_ALL) {
14527                // But first, if this is not a broadcast to all users, then
14528                // make sure it doesn't conflict with an existing broadcast to
14529                // all users.
14530                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14531                        UserHandle.USER_ALL);
14532                if (stickies != null) {
14533                    ArrayList<Intent> list = stickies.get(intent.getAction());
14534                    if (list != null) {
14535                        int N = list.size();
14536                        int i;
14537                        for (i=0; i<N; i++) {
14538                            if (intent.filterEquals(list.get(i))) {
14539                                throw new IllegalArgumentException(
14540                                        "Sticky broadcast " + intent + " for user "
14541                                        + userId + " conflicts with existing global broadcast");
14542                            }
14543                        }
14544                    }
14545                }
14546            }
14547            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14548            if (stickies == null) {
14549                stickies = new ArrayMap<String, ArrayList<Intent>>();
14550                mStickyBroadcasts.put(userId, stickies);
14551            }
14552            ArrayList<Intent> list = stickies.get(intent.getAction());
14553            if (list == null) {
14554                list = new ArrayList<Intent>();
14555                stickies.put(intent.getAction(), list);
14556            }
14557            int N = list.size();
14558            int i;
14559            for (i=0; i<N; i++) {
14560                if (intent.filterEquals(list.get(i))) {
14561                    // This sticky already exists, replace it.
14562                    list.set(i, new Intent(intent));
14563                    break;
14564                }
14565            }
14566            if (i >= N) {
14567                list.add(new Intent(intent));
14568            }
14569        }
14570
14571        int[] users;
14572        if (userId == UserHandle.USER_ALL) {
14573            // Caller wants broadcast to go to all started users.
14574            users = mStartedUserArray;
14575        } else {
14576            // Caller wants broadcast to go to one specific user.
14577            users = new int[] {userId};
14578        }
14579
14580        // Figure out who all will receive this broadcast.
14581        List receivers = null;
14582        List<BroadcastFilter> registeredReceivers = null;
14583        // Need to resolve the intent to interested receivers...
14584        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14585                 == 0) {
14586            receivers = collectReceiverComponents(intent, resolvedType, users);
14587        }
14588        if (intent.getComponent() == null) {
14589            registeredReceivers = mReceiverResolver.queryIntent(intent,
14590                    resolvedType, false, userId);
14591        }
14592
14593        final boolean replacePending =
14594                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14595
14596        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14597                + " replacePending=" + replacePending);
14598
14599        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14600        if (!ordered && NR > 0) {
14601            // If we are not serializing this broadcast, then send the
14602            // registered receivers separately so they don't wait for the
14603            // components to be launched.
14604            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14605            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14606                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14607                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14608                    ordered, sticky, false, userId);
14609            if (DEBUG_BROADCAST) Slog.v(
14610                    TAG, "Enqueueing parallel broadcast " + r);
14611            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14612            if (!replaced) {
14613                queue.enqueueParallelBroadcastLocked(r);
14614                queue.scheduleBroadcastsLocked();
14615            }
14616            registeredReceivers = null;
14617            NR = 0;
14618        }
14619
14620        // Merge into one list.
14621        int ir = 0;
14622        if (receivers != null) {
14623            // A special case for PACKAGE_ADDED: do not allow the package
14624            // being added to see this broadcast.  This prevents them from
14625            // using this as a back door to get run as soon as they are
14626            // installed.  Maybe in the future we want to have a special install
14627            // broadcast or such for apps, but we'd like to deliberately make
14628            // this decision.
14629            String skipPackages[] = null;
14630            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14631                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14632                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14633                Uri data = intent.getData();
14634                if (data != null) {
14635                    String pkgName = data.getSchemeSpecificPart();
14636                    if (pkgName != null) {
14637                        skipPackages = new String[] { pkgName };
14638                    }
14639                }
14640            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14641                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14642            }
14643            if (skipPackages != null && (skipPackages.length > 0)) {
14644                for (String skipPackage : skipPackages) {
14645                    if (skipPackage != null) {
14646                        int NT = receivers.size();
14647                        for (int it=0; it<NT; it++) {
14648                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14649                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14650                                receivers.remove(it);
14651                                it--;
14652                                NT--;
14653                            }
14654                        }
14655                    }
14656                }
14657            }
14658
14659            int NT = receivers != null ? receivers.size() : 0;
14660            int it = 0;
14661            ResolveInfo curt = null;
14662            BroadcastFilter curr = null;
14663            while (it < NT && ir < NR) {
14664                if (curt == null) {
14665                    curt = (ResolveInfo)receivers.get(it);
14666                }
14667                if (curr == null) {
14668                    curr = registeredReceivers.get(ir);
14669                }
14670                if (curr.getPriority() >= curt.priority) {
14671                    // Insert this broadcast record into the final list.
14672                    receivers.add(it, curr);
14673                    ir++;
14674                    curr = null;
14675                    it++;
14676                    NT++;
14677                } else {
14678                    // Skip to the next ResolveInfo in the final list.
14679                    it++;
14680                    curt = null;
14681                }
14682            }
14683        }
14684        while (ir < NR) {
14685            if (receivers == null) {
14686                receivers = new ArrayList();
14687            }
14688            receivers.add(registeredReceivers.get(ir));
14689            ir++;
14690        }
14691
14692        if ((receivers != null && receivers.size() > 0)
14693                || resultTo != null) {
14694            BroadcastQueue queue = broadcastQueueForIntent(intent);
14695            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14696                    callerPackage, callingPid, callingUid, resolvedType,
14697                    requiredPermission, appOp, receivers, resultTo, resultCode,
14698                    resultData, map, ordered, sticky, false, userId);
14699            if (DEBUG_BROADCAST) Slog.v(
14700                    TAG, "Enqueueing ordered broadcast " + r
14701                    + ": prev had " + queue.mOrderedBroadcasts.size());
14702            if (DEBUG_BROADCAST) {
14703                int seq = r.intent.getIntExtra("seq", -1);
14704                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14705            }
14706            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14707            if (!replaced) {
14708                queue.enqueueOrderedBroadcastLocked(r);
14709                queue.scheduleBroadcastsLocked();
14710            }
14711        }
14712
14713        return ActivityManager.BROADCAST_SUCCESS;
14714    }
14715
14716    final Intent verifyBroadcastLocked(Intent intent) {
14717        // Refuse possible leaked file descriptors
14718        if (intent != null && intent.hasFileDescriptors() == true) {
14719            throw new IllegalArgumentException("File descriptors passed in Intent");
14720        }
14721
14722        int flags = intent.getFlags();
14723
14724        if (!mProcessesReady) {
14725            // if the caller really truly claims to know what they're doing, go
14726            // ahead and allow the broadcast without launching any receivers
14727            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14728                intent = new Intent(intent);
14729                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14730            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14731                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14732                        + " before boot completion");
14733                throw new IllegalStateException("Cannot broadcast before boot completed");
14734            }
14735        }
14736
14737        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14738            throw new IllegalArgumentException(
14739                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14740        }
14741
14742        return intent;
14743    }
14744
14745    public final int broadcastIntent(IApplicationThread caller,
14746            Intent intent, String resolvedType, IIntentReceiver resultTo,
14747            int resultCode, String resultData, Bundle map,
14748            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14749        enforceNotIsolatedCaller("broadcastIntent");
14750        synchronized(this) {
14751            intent = verifyBroadcastLocked(intent);
14752
14753            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14754            final int callingPid = Binder.getCallingPid();
14755            final int callingUid = Binder.getCallingUid();
14756            final long origId = Binder.clearCallingIdentity();
14757            int res = broadcastIntentLocked(callerApp,
14758                    callerApp != null ? callerApp.info.packageName : null,
14759                    intent, resolvedType, resultTo,
14760                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14761                    callingPid, callingUid, userId);
14762            Binder.restoreCallingIdentity(origId);
14763            return res;
14764        }
14765    }
14766
14767    int broadcastIntentInPackage(String packageName, int uid,
14768            Intent intent, String resolvedType, IIntentReceiver resultTo,
14769            int resultCode, String resultData, Bundle map,
14770            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14771        synchronized(this) {
14772            intent = verifyBroadcastLocked(intent);
14773
14774            final long origId = Binder.clearCallingIdentity();
14775            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14776                    resultTo, resultCode, resultData, map, requiredPermission,
14777                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14778            Binder.restoreCallingIdentity(origId);
14779            return res;
14780        }
14781    }
14782
14783    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14784        // Refuse possible leaked file descriptors
14785        if (intent != null && intent.hasFileDescriptors() == true) {
14786            throw new IllegalArgumentException("File descriptors passed in Intent");
14787        }
14788
14789        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14790                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14791
14792        synchronized(this) {
14793            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14794                    != PackageManager.PERMISSION_GRANTED) {
14795                String msg = "Permission Denial: unbroadcastIntent() from pid="
14796                        + Binder.getCallingPid()
14797                        + ", uid=" + Binder.getCallingUid()
14798                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14799                Slog.w(TAG, msg);
14800                throw new SecurityException(msg);
14801            }
14802            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14803            if (stickies != null) {
14804                ArrayList<Intent> list = stickies.get(intent.getAction());
14805                if (list != null) {
14806                    int N = list.size();
14807                    int i;
14808                    for (i=0; i<N; i++) {
14809                        if (intent.filterEquals(list.get(i))) {
14810                            list.remove(i);
14811                            break;
14812                        }
14813                    }
14814                    if (list.size() <= 0) {
14815                        stickies.remove(intent.getAction());
14816                    }
14817                }
14818                if (stickies.size() <= 0) {
14819                    mStickyBroadcasts.remove(userId);
14820                }
14821            }
14822        }
14823    }
14824
14825    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14826            String resultData, Bundle resultExtras, boolean resultAbort) {
14827        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14828        if (r == null) {
14829            Slog.w(TAG, "finishReceiver called but not found on queue");
14830            return false;
14831        }
14832
14833        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14834    }
14835
14836    void backgroundServicesFinishedLocked(int userId) {
14837        for (BroadcastQueue queue : mBroadcastQueues) {
14838            queue.backgroundServicesFinishedLocked(userId);
14839        }
14840    }
14841
14842    public void finishReceiver(IBinder who, int resultCode, String resultData,
14843            Bundle resultExtras, boolean resultAbort) {
14844        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14845
14846        // Refuse possible leaked file descriptors
14847        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14848            throw new IllegalArgumentException("File descriptors passed in Bundle");
14849        }
14850
14851        final long origId = Binder.clearCallingIdentity();
14852        try {
14853            boolean doNext = false;
14854            BroadcastRecord r;
14855
14856            synchronized(this) {
14857                r = broadcastRecordForReceiverLocked(who);
14858                if (r != null) {
14859                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14860                        resultData, resultExtras, resultAbort, true);
14861                }
14862            }
14863
14864            if (doNext) {
14865                r.queue.processNextBroadcast(false);
14866            }
14867            trimApplications();
14868        } finally {
14869            Binder.restoreCallingIdentity(origId);
14870        }
14871    }
14872
14873    // =========================================================
14874    // INSTRUMENTATION
14875    // =========================================================
14876
14877    public boolean startInstrumentation(ComponentName className,
14878            String profileFile, int flags, Bundle arguments,
14879            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14880            int userId, String abiOverride) {
14881        enforceNotIsolatedCaller("startInstrumentation");
14882        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14883                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14884        // Refuse possible leaked file descriptors
14885        if (arguments != null && arguments.hasFileDescriptors()) {
14886            throw new IllegalArgumentException("File descriptors passed in Bundle");
14887        }
14888
14889        synchronized(this) {
14890            InstrumentationInfo ii = null;
14891            ApplicationInfo ai = null;
14892            try {
14893                ii = mContext.getPackageManager().getInstrumentationInfo(
14894                    className, STOCK_PM_FLAGS);
14895                ai = AppGlobals.getPackageManager().getApplicationInfo(
14896                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14897            } catch (PackageManager.NameNotFoundException e) {
14898            } catch (RemoteException e) {
14899            }
14900            if (ii == null) {
14901                reportStartInstrumentationFailure(watcher, className,
14902                        "Unable to find instrumentation info for: " + className);
14903                return false;
14904            }
14905            if (ai == null) {
14906                reportStartInstrumentationFailure(watcher, className,
14907                        "Unable to find instrumentation target package: " + ii.targetPackage);
14908                return false;
14909            }
14910
14911            int match = mContext.getPackageManager().checkSignatures(
14912                    ii.targetPackage, ii.packageName);
14913            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14914                String msg = "Permission Denial: starting instrumentation "
14915                        + className + " from pid="
14916                        + Binder.getCallingPid()
14917                        + ", uid=" + Binder.getCallingPid()
14918                        + " not allowed because package " + ii.packageName
14919                        + " does not have a signature matching the target "
14920                        + ii.targetPackage;
14921                reportStartInstrumentationFailure(watcher, className, msg);
14922                throw new SecurityException(msg);
14923            }
14924
14925            final long origId = Binder.clearCallingIdentity();
14926            // Instrumentation can kill and relaunch even persistent processes
14927            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14928                    "start instr");
14929            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14930            app.instrumentationClass = className;
14931            app.instrumentationInfo = ai;
14932            app.instrumentationProfileFile = profileFile;
14933            app.instrumentationArguments = arguments;
14934            app.instrumentationWatcher = watcher;
14935            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14936            app.instrumentationResultClass = className;
14937            Binder.restoreCallingIdentity(origId);
14938        }
14939
14940        return true;
14941    }
14942
14943    /**
14944     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14945     * error to the logs, but if somebody is watching, send the report there too.  This enables
14946     * the "am" command to report errors with more information.
14947     *
14948     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14949     * @param cn The component name of the instrumentation.
14950     * @param report The error report.
14951     */
14952    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14953            ComponentName cn, String report) {
14954        Slog.w(TAG, report);
14955        try {
14956            if (watcher != null) {
14957                Bundle results = new Bundle();
14958                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14959                results.putString("Error", report);
14960                watcher.instrumentationStatus(cn, -1, results);
14961            }
14962        } catch (RemoteException e) {
14963            Slog.w(TAG, e);
14964        }
14965    }
14966
14967    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14968        if (app.instrumentationWatcher != null) {
14969            try {
14970                // NOTE:  IInstrumentationWatcher *must* be oneway here
14971                app.instrumentationWatcher.instrumentationFinished(
14972                    app.instrumentationClass,
14973                    resultCode,
14974                    results);
14975            } catch (RemoteException e) {
14976            }
14977        }
14978        if (app.instrumentationUiAutomationConnection != null) {
14979            try {
14980                app.instrumentationUiAutomationConnection.shutdown();
14981            } catch (RemoteException re) {
14982                /* ignore */
14983            }
14984            // Only a UiAutomation can set this flag and now that
14985            // it is finished we make sure it is reset to its default.
14986            mUserIsMonkey = false;
14987        }
14988        app.instrumentationWatcher = null;
14989        app.instrumentationUiAutomationConnection = null;
14990        app.instrumentationClass = null;
14991        app.instrumentationInfo = null;
14992        app.instrumentationProfileFile = null;
14993        app.instrumentationArguments = null;
14994
14995        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14996                "finished inst");
14997    }
14998
14999    public void finishInstrumentation(IApplicationThread target,
15000            int resultCode, Bundle results) {
15001        int userId = UserHandle.getCallingUserId();
15002        // Refuse possible leaked file descriptors
15003        if (results != null && results.hasFileDescriptors()) {
15004            throw new IllegalArgumentException("File descriptors passed in Intent");
15005        }
15006
15007        synchronized(this) {
15008            ProcessRecord app = getRecordForAppLocked(target);
15009            if (app == null) {
15010                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15011                return;
15012            }
15013            final long origId = Binder.clearCallingIdentity();
15014            finishInstrumentationLocked(app, resultCode, results);
15015            Binder.restoreCallingIdentity(origId);
15016        }
15017    }
15018
15019    // =========================================================
15020    // CONFIGURATION
15021    // =========================================================
15022
15023    public ConfigurationInfo getDeviceConfigurationInfo() {
15024        ConfigurationInfo config = new ConfigurationInfo();
15025        synchronized (this) {
15026            config.reqTouchScreen = mConfiguration.touchscreen;
15027            config.reqKeyboardType = mConfiguration.keyboard;
15028            config.reqNavigation = mConfiguration.navigation;
15029            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15030                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15031                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15032            }
15033            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15034                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15035                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15036            }
15037            config.reqGlEsVersion = GL_ES_VERSION;
15038        }
15039        return config;
15040    }
15041
15042    ActivityStack getFocusedStack() {
15043        return mStackSupervisor.getFocusedStack();
15044    }
15045
15046    public Configuration getConfiguration() {
15047        Configuration ci;
15048        synchronized(this) {
15049            ci = new Configuration(mConfiguration);
15050        }
15051        return ci;
15052    }
15053
15054    public void updatePersistentConfiguration(Configuration values) {
15055        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15056                "updateConfiguration()");
15057        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15058                "updateConfiguration()");
15059        if (values == null) {
15060            throw new NullPointerException("Configuration must not be null");
15061        }
15062
15063        synchronized(this) {
15064            final long origId = Binder.clearCallingIdentity();
15065            updateConfigurationLocked(values, null, true, false);
15066            Binder.restoreCallingIdentity(origId);
15067        }
15068    }
15069
15070    public void updateConfiguration(Configuration values) {
15071        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15072                "updateConfiguration()");
15073
15074        synchronized(this) {
15075            if (values == null && mWindowManager != null) {
15076                // sentinel: fetch the current configuration from the window manager
15077                values = mWindowManager.computeNewConfiguration();
15078            }
15079
15080            if (mWindowManager != null) {
15081                mProcessList.applyDisplaySize(mWindowManager);
15082            }
15083
15084            final long origId = Binder.clearCallingIdentity();
15085            if (values != null) {
15086                Settings.System.clearConfiguration(values);
15087            }
15088            updateConfigurationLocked(values, null, false, false);
15089            Binder.restoreCallingIdentity(origId);
15090        }
15091    }
15092
15093    /**
15094     * Do either or both things: (1) change the current configuration, and (2)
15095     * make sure the given activity is running with the (now) current
15096     * configuration.  Returns true if the activity has been left running, or
15097     * false if <var>starting</var> is being destroyed to match the new
15098     * configuration.
15099     * @param persistent TODO
15100     */
15101    boolean updateConfigurationLocked(Configuration values,
15102            ActivityRecord starting, boolean persistent, boolean initLocale) {
15103        int changes = 0;
15104
15105        if (values != null) {
15106            Configuration newConfig = new Configuration(mConfiguration);
15107            changes = newConfig.updateFrom(values);
15108            if (changes != 0) {
15109                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15110                    Slog.i(TAG, "Updating configuration to: " + values);
15111                }
15112
15113                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15114
15115                if (values.locale != null && !initLocale) {
15116                    saveLocaleLocked(values.locale,
15117                                     !values.locale.equals(mConfiguration.locale),
15118                                     values.userSetLocale);
15119                }
15120
15121                mConfigurationSeq++;
15122                if (mConfigurationSeq <= 0) {
15123                    mConfigurationSeq = 1;
15124                }
15125                newConfig.seq = mConfigurationSeq;
15126                mConfiguration = newConfig;
15127                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15128                //mUsageStatsService.noteStartConfig(newConfig);
15129
15130                final Configuration configCopy = new Configuration(mConfiguration);
15131
15132                // TODO: If our config changes, should we auto dismiss any currently
15133                // showing dialogs?
15134                mShowDialogs = shouldShowDialogs(newConfig);
15135
15136                AttributeCache ac = AttributeCache.instance();
15137                if (ac != null) {
15138                    ac.updateConfiguration(configCopy);
15139                }
15140
15141                // Make sure all resources in our process are updated
15142                // right now, so that anyone who is going to retrieve
15143                // resource values after we return will be sure to get
15144                // the new ones.  This is especially important during
15145                // boot, where the first config change needs to guarantee
15146                // all resources have that config before following boot
15147                // code is executed.
15148                mSystemThread.applyConfigurationToResources(configCopy);
15149
15150                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15151                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15152                    msg.obj = new Configuration(configCopy);
15153                    mHandler.sendMessage(msg);
15154                }
15155
15156                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15157                    ProcessRecord app = mLruProcesses.get(i);
15158                    try {
15159                        if (app.thread != null) {
15160                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15161                                    + app.processName + " new config " + mConfiguration);
15162                            app.thread.scheduleConfigurationChanged(configCopy);
15163                        }
15164                    } catch (Exception e) {
15165                    }
15166                }
15167                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15168                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15169                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15170                        | Intent.FLAG_RECEIVER_FOREGROUND);
15171                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15172                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15173                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15174                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15175                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15176                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15177                    broadcastIntentLocked(null, null, intent,
15178                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15179                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15180                }
15181            }
15182        }
15183
15184        boolean kept = true;
15185        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15186        // mainStack is null during startup.
15187        if (mainStack != null) {
15188            if (changes != 0 && starting == null) {
15189                // If the configuration changed, and the caller is not already
15190                // in the process of starting an activity, then find the top
15191                // activity to check if its configuration needs to change.
15192                starting = mainStack.topRunningActivityLocked(null);
15193            }
15194
15195            if (starting != null) {
15196                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15197                // And we need to make sure at this point that all other activities
15198                // are made visible with the correct configuration.
15199                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15200            }
15201        }
15202
15203        if (values != null && mWindowManager != null) {
15204            mWindowManager.setNewConfiguration(mConfiguration);
15205        }
15206
15207        return kept;
15208    }
15209
15210    /**
15211     * Decide based on the configuration whether we should shouw the ANR,
15212     * crash, etc dialogs.  The idea is that if there is no affordnace to
15213     * press the on-screen buttons, we shouldn't show the dialog.
15214     *
15215     * A thought: SystemUI might also want to get told about this, the Power
15216     * dialog / global actions also might want different behaviors.
15217     */
15218    private static final boolean shouldShowDialogs(Configuration config) {
15219        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15220                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15221    }
15222
15223    /**
15224     * Save the locale.  You must be inside a synchronized (this) block.
15225     */
15226    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15227        if(isDiff) {
15228            SystemProperties.set("user.language", l.getLanguage());
15229            SystemProperties.set("user.region", l.getCountry());
15230        }
15231
15232        if(isPersist) {
15233            SystemProperties.set("persist.sys.language", l.getLanguage());
15234            SystemProperties.set("persist.sys.country", l.getCountry());
15235            SystemProperties.set("persist.sys.localevar", l.getVariant());
15236        }
15237    }
15238
15239    @Override
15240    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15241        ActivityRecord srec = ActivityRecord.forToken(token);
15242        return srec != null && srec.task.affinity != null &&
15243                srec.task.affinity.equals(destAffinity);
15244    }
15245
15246    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15247            Intent resultData) {
15248
15249        synchronized (this) {
15250            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15251            if (stack != null) {
15252                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15253            }
15254            return false;
15255        }
15256    }
15257
15258    public int getLaunchedFromUid(IBinder activityToken) {
15259        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15260        if (srec == null) {
15261            return -1;
15262        }
15263        return srec.launchedFromUid;
15264    }
15265
15266    public String getLaunchedFromPackage(IBinder activityToken) {
15267        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15268        if (srec == null) {
15269            return null;
15270        }
15271        return srec.launchedFromPackage;
15272    }
15273
15274    // =========================================================
15275    // LIFETIME MANAGEMENT
15276    // =========================================================
15277
15278    // Returns which broadcast queue the app is the current [or imminent] receiver
15279    // on, or 'null' if the app is not an active broadcast recipient.
15280    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15281        BroadcastRecord r = app.curReceiver;
15282        if (r != null) {
15283            return r.queue;
15284        }
15285
15286        // It's not the current receiver, but it might be starting up to become one
15287        synchronized (this) {
15288            for (BroadcastQueue queue : mBroadcastQueues) {
15289                r = queue.mPendingBroadcast;
15290                if (r != null && r.curApp == app) {
15291                    // found it; report which queue it's in
15292                    return queue;
15293                }
15294            }
15295        }
15296
15297        return null;
15298    }
15299
15300    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15301            boolean doingAll, long now) {
15302        if (mAdjSeq == app.adjSeq) {
15303            // This adjustment has already been computed.
15304            return app.curRawAdj;
15305        }
15306
15307        if (app.thread == null) {
15308            app.adjSeq = mAdjSeq;
15309            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15310            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15311            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15312        }
15313
15314        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15315        app.adjSource = null;
15316        app.adjTarget = null;
15317        app.empty = false;
15318        app.cached = false;
15319
15320        final int activitiesSize = app.activities.size();
15321
15322        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15323            // The max adjustment doesn't allow this app to be anything
15324            // below foreground, so it is not worth doing work for it.
15325            app.adjType = "fixed";
15326            app.adjSeq = mAdjSeq;
15327            app.curRawAdj = app.maxAdj;
15328            app.foregroundActivities = false;
15329            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15330            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15331            // System processes can do UI, and when they do we want to have
15332            // them trim their memory after the user leaves the UI.  To
15333            // facilitate this, here we need to determine whether or not it
15334            // is currently showing UI.
15335            app.systemNoUi = true;
15336            if (app == TOP_APP) {
15337                app.systemNoUi = false;
15338            } else if (activitiesSize > 0) {
15339                for (int j = 0; j < activitiesSize; j++) {
15340                    final ActivityRecord r = app.activities.get(j);
15341                    if (r.visible) {
15342                        app.systemNoUi = false;
15343                    }
15344                }
15345            }
15346            if (!app.systemNoUi) {
15347                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15348            }
15349            return (app.curAdj=app.maxAdj);
15350        }
15351
15352        app.systemNoUi = false;
15353
15354        // Determine the importance of the process, starting with most
15355        // important to least, and assign an appropriate OOM adjustment.
15356        int adj;
15357        int schedGroup;
15358        int procState;
15359        boolean foregroundActivities = false;
15360        BroadcastQueue queue;
15361        if (app == TOP_APP) {
15362            // The last app on the list is the foreground app.
15363            adj = ProcessList.FOREGROUND_APP_ADJ;
15364            schedGroup = Process.THREAD_GROUP_DEFAULT;
15365            app.adjType = "top-activity";
15366            foregroundActivities = true;
15367            procState = ActivityManager.PROCESS_STATE_TOP;
15368        } else if (app.instrumentationClass != null) {
15369            // Don't want to kill running instrumentation.
15370            adj = ProcessList.FOREGROUND_APP_ADJ;
15371            schedGroup = Process.THREAD_GROUP_DEFAULT;
15372            app.adjType = "instrumentation";
15373            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15374        } else if ((queue = isReceivingBroadcast(app)) != null) {
15375            // An app that is currently receiving a broadcast also
15376            // counts as being in the foreground for OOM killer purposes.
15377            // It's placed in a sched group based on the nature of the
15378            // broadcast as reflected by which queue it's active in.
15379            adj = ProcessList.FOREGROUND_APP_ADJ;
15380            schedGroup = (queue == mFgBroadcastQueue)
15381                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15382            app.adjType = "broadcast";
15383            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15384        } else if (app.executingServices.size() > 0) {
15385            // An app that is currently executing a service callback also
15386            // counts as being in the foreground.
15387            adj = ProcessList.FOREGROUND_APP_ADJ;
15388            schedGroup = app.execServicesFg ?
15389                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15390            app.adjType = "exec-service";
15391            procState = ActivityManager.PROCESS_STATE_SERVICE;
15392            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15393        } else {
15394            // As far as we know the process is empty.  We may change our mind later.
15395            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15396            // At this point we don't actually know the adjustment.  Use the cached adj
15397            // value that the caller wants us to.
15398            adj = cachedAdj;
15399            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15400            app.cached = true;
15401            app.empty = true;
15402            app.adjType = "cch-empty";
15403        }
15404
15405        // Examine all activities if not already foreground.
15406        if (!foregroundActivities && activitiesSize > 0) {
15407            for (int j = 0; j < activitiesSize; j++) {
15408                final ActivityRecord r = app.activities.get(j);
15409                if (r.app != app) {
15410                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15411                            + app + "?!?");
15412                    continue;
15413                }
15414                if (r.visible) {
15415                    // App has a visible activity; only upgrade adjustment.
15416                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15417                        adj = ProcessList.VISIBLE_APP_ADJ;
15418                        app.adjType = "visible";
15419                    }
15420                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15421                        procState = ActivityManager.PROCESS_STATE_TOP;
15422                    }
15423                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15424                    app.cached = false;
15425                    app.empty = false;
15426                    foregroundActivities = true;
15427                    break;
15428                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15429                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15430                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15431                        app.adjType = "pausing";
15432                    }
15433                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15434                        procState = ActivityManager.PROCESS_STATE_TOP;
15435                    }
15436                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15437                    app.cached = false;
15438                    app.empty = false;
15439                    foregroundActivities = true;
15440                } else if (r.state == ActivityState.STOPPING) {
15441                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15442                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15443                        app.adjType = "stopping";
15444                    }
15445                    // For the process state, we will at this point consider the
15446                    // process to be cached.  It will be cached either as an activity
15447                    // or empty depending on whether the activity is finishing.  We do
15448                    // this so that we can treat the process as cached for purposes of
15449                    // memory trimming (determing current memory level, trim command to
15450                    // send to process) since there can be an arbitrary number of stopping
15451                    // processes and they should soon all go into the cached state.
15452                    if (!r.finishing) {
15453                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15454                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15455                        }
15456                    }
15457                    app.cached = false;
15458                    app.empty = false;
15459                    foregroundActivities = true;
15460                } else {
15461                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15462                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15463                        app.adjType = "cch-act";
15464                    }
15465                }
15466            }
15467        }
15468
15469        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15470            if (app.foregroundServices) {
15471                // The user is aware of this app, so make it visible.
15472                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15473                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15474                app.cached = false;
15475                app.adjType = "fg-service";
15476                schedGroup = Process.THREAD_GROUP_DEFAULT;
15477            } else if (app.forcingToForeground != null) {
15478                // The user is aware of this app, so make it visible.
15479                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15480                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15481                app.cached = false;
15482                app.adjType = "force-fg";
15483                app.adjSource = app.forcingToForeground;
15484                schedGroup = Process.THREAD_GROUP_DEFAULT;
15485            }
15486        }
15487
15488        if (app == mHeavyWeightProcess) {
15489            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15490                // We don't want to kill the current heavy-weight process.
15491                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15492                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15493                app.cached = false;
15494                app.adjType = "heavy";
15495            }
15496            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15497                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15498            }
15499        }
15500
15501        if (app == mHomeProcess) {
15502            if (adj > ProcessList.HOME_APP_ADJ) {
15503                // This process is hosting what we currently consider to be the
15504                // home app, so we don't want to let it go into the background.
15505                adj = ProcessList.HOME_APP_ADJ;
15506                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15507                app.cached = false;
15508                app.adjType = "home";
15509            }
15510            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15511                procState = ActivityManager.PROCESS_STATE_HOME;
15512            }
15513        }
15514
15515        if (app == mPreviousProcess && app.activities.size() > 0) {
15516            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15517                // This was the previous process that showed UI to the user.
15518                // We want to try to keep it around more aggressively, to give
15519                // a good experience around switching between two apps.
15520                adj = ProcessList.PREVIOUS_APP_ADJ;
15521                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15522                app.cached = false;
15523                app.adjType = "previous";
15524            }
15525            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15526                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15527            }
15528        }
15529
15530        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15531                + " reason=" + app.adjType);
15532
15533        // By default, we use the computed adjustment.  It may be changed if
15534        // there are applications dependent on our services or providers, but
15535        // this gives us a baseline and makes sure we don't get into an
15536        // infinite recursion.
15537        app.adjSeq = mAdjSeq;
15538        app.curRawAdj = adj;
15539        app.hasStartedServices = false;
15540
15541        if (mBackupTarget != null && app == mBackupTarget.app) {
15542            // If possible we want to avoid killing apps while they're being backed up
15543            if (adj > ProcessList.BACKUP_APP_ADJ) {
15544                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15545                adj = ProcessList.BACKUP_APP_ADJ;
15546                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15547                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15548                }
15549                app.adjType = "backup";
15550                app.cached = false;
15551            }
15552            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15553                procState = ActivityManager.PROCESS_STATE_BACKUP;
15554            }
15555        }
15556
15557        boolean mayBeTop = false;
15558
15559        for (int is = app.services.size()-1;
15560                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15561                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15562                        || procState > ActivityManager.PROCESS_STATE_TOP);
15563                is--) {
15564            ServiceRecord s = app.services.valueAt(is);
15565            if (s.startRequested) {
15566                app.hasStartedServices = true;
15567                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15568                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15569                }
15570                if (app.hasShownUi && app != mHomeProcess) {
15571                    // If this process has shown some UI, let it immediately
15572                    // go to the LRU list because it may be pretty heavy with
15573                    // UI stuff.  We'll tag it with a label just to help
15574                    // debug and understand what is going on.
15575                    if (adj > ProcessList.SERVICE_ADJ) {
15576                        app.adjType = "cch-started-ui-services";
15577                    }
15578                } else {
15579                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15580                        // This service has seen some activity within
15581                        // recent memory, so we will keep its process ahead
15582                        // of the background processes.
15583                        if (adj > ProcessList.SERVICE_ADJ) {
15584                            adj = ProcessList.SERVICE_ADJ;
15585                            app.adjType = "started-services";
15586                            app.cached = false;
15587                        }
15588                    }
15589                    // If we have let the service slide into the background
15590                    // state, still have some text describing what it is doing
15591                    // even though the service no longer has an impact.
15592                    if (adj > ProcessList.SERVICE_ADJ) {
15593                        app.adjType = "cch-started-services";
15594                    }
15595                }
15596            }
15597            for (int conni = s.connections.size()-1;
15598                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15599                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15600                            || procState > ActivityManager.PROCESS_STATE_TOP);
15601                    conni--) {
15602                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15603                for (int i = 0;
15604                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15605                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15606                                || procState > ActivityManager.PROCESS_STATE_TOP);
15607                        i++) {
15608                    // XXX should compute this based on the max of
15609                    // all connected clients.
15610                    ConnectionRecord cr = clist.get(i);
15611                    if (cr.binding.client == app) {
15612                        // Binding to ourself is not interesting.
15613                        continue;
15614                    }
15615                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15616                        ProcessRecord client = cr.binding.client;
15617                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15618                                TOP_APP, doingAll, now);
15619                        int clientProcState = client.curProcState;
15620                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15621                            // If the other app is cached for any reason, for purposes here
15622                            // we are going to consider it empty.  The specific cached state
15623                            // doesn't propagate except under certain conditions.
15624                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15625                        }
15626                        String adjType = null;
15627                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15628                            // Not doing bind OOM management, so treat
15629                            // this guy more like a started service.
15630                            if (app.hasShownUi && app != mHomeProcess) {
15631                                // If this process has shown some UI, let it immediately
15632                                // go to the LRU list because it may be pretty heavy with
15633                                // UI stuff.  We'll tag it with a label just to help
15634                                // debug and understand what is going on.
15635                                if (adj > clientAdj) {
15636                                    adjType = "cch-bound-ui-services";
15637                                }
15638                                app.cached = false;
15639                                clientAdj = adj;
15640                                clientProcState = procState;
15641                            } else {
15642                                if (now >= (s.lastActivity
15643                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15644                                    // This service has not seen activity within
15645                                    // recent memory, so allow it to drop to the
15646                                    // LRU list if there is no other reason to keep
15647                                    // it around.  We'll also tag it with a label just
15648                                    // to help debug and undertand what is going on.
15649                                    if (adj > clientAdj) {
15650                                        adjType = "cch-bound-services";
15651                                    }
15652                                    clientAdj = adj;
15653                                }
15654                            }
15655                        }
15656                        if (adj > clientAdj) {
15657                            // If this process has recently shown UI, and
15658                            // the process that is binding to it is less
15659                            // important than being visible, then we don't
15660                            // care about the binding as much as we care
15661                            // about letting this process get into the LRU
15662                            // list to be killed and restarted if needed for
15663                            // memory.
15664                            if (app.hasShownUi && app != mHomeProcess
15665                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15666                                adjType = "cch-bound-ui-services";
15667                            } else {
15668                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15669                                        |Context.BIND_IMPORTANT)) != 0) {
15670                                    adj = clientAdj;
15671                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15672                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15673                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15674                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15675                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15676                                    adj = clientAdj;
15677                                } else {
15678                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15679                                        adj = ProcessList.VISIBLE_APP_ADJ;
15680                                    }
15681                                }
15682                                if (!client.cached) {
15683                                    app.cached = false;
15684                                }
15685                                adjType = "service";
15686                            }
15687                        }
15688                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15689                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15690                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15691                            }
15692                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15693                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15694                                    // Special handling of clients who are in the top state.
15695                                    // We *may* want to consider this process to be in the
15696                                    // top state as well, but only if there is not another
15697                                    // reason for it to be running.  Being on the top is a
15698                                    // special state, meaning you are specifically running
15699                                    // for the current top app.  If the process is already
15700                                    // running in the background for some other reason, it
15701                                    // is more important to continue considering it to be
15702                                    // in the background state.
15703                                    mayBeTop = true;
15704                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15705                                } else {
15706                                    // Special handling for above-top states (persistent
15707                                    // processes).  These should not bring the current process
15708                                    // into the top state, since they are not on top.  Instead
15709                                    // give them the best state after that.
15710                                    clientProcState =
15711                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15712                                }
15713                            }
15714                        } else {
15715                            if (clientProcState <
15716                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15717                                clientProcState =
15718                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15719                            }
15720                        }
15721                        if (procState > clientProcState) {
15722                            procState = clientProcState;
15723                        }
15724                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15725                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15726                            app.pendingUiClean = true;
15727                        }
15728                        if (adjType != null) {
15729                            app.adjType = adjType;
15730                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15731                                    .REASON_SERVICE_IN_USE;
15732                            app.adjSource = cr.binding.client;
15733                            app.adjSourceProcState = clientProcState;
15734                            app.adjTarget = s.name;
15735                        }
15736                    }
15737                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15738                        app.treatLikeActivity = true;
15739                    }
15740                    final ActivityRecord a = cr.activity;
15741                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15742                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15743                                (a.visible || a.state == ActivityState.RESUMED
15744                                 || a.state == ActivityState.PAUSING)) {
15745                            adj = ProcessList.FOREGROUND_APP_ADJ;
15746                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15747                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15748                            }
15749                            app.cached = false;
15750                            app.adjType = "service";
15751                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15752                                    .REASON_SERVICE_IN_USE;
15753                            app.adjSource = a;
15754                            app.adjSourceProcState = procState;
15755                            app.adjTarget = s.name;
15756                        }
15757                    }
15758                }
15759            }
15760        }
15761
15762        for (int provi = app.pubProviders.size()-1;
15763                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15764                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15765                        || procState > ActivityManager.PROCESS_STATE_TOP);
15766                provi--) {
15767            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15768            for (int i = cpr.connections.size()-1;
15769                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15770                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15771                            || procState > ActivityManager.PROCESS_STATE_TOP);
15772                    i--) {
15773                ContentProviderConnection conn = cpr.connections.get(i);
15774                ProcessRecord client = conn.client;
15775                if (client == app) {
15776                    // Being our own client is not interesting.
15777                    continue;
15778                }
15779                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15780                int clientProcState = client.curProcState;
15781                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15782                    // If the other app is cached for any reason, for purposes here
15783                    // we are going to consider it empty.
15784                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15785                }
15786                if (adj > clientAdj) {
15787                    if (app.hasShownUi && app != mHomeProcess
15788                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15789                        app.adjType = "cch-ui-provider";
15790                    } else {
15791                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15792                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15793                        app.adjType = "provider";
15794                    }
15795                    app.cached &= client.cached;
15796                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15797                            .REASON_PROVIDER_IN_USE;
15798                    app.adjSource = client;
15799                    app.adjSourceProcState = clientProcState;
15800                    app.adjTarget = cpr.name;
15801                }
15802                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15803                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15804                        // Special handling of clients who are in the top state.
15805                        // We *may* want to consider this process to be in the
15806                        // top state as well, but only if there is not another
15807                        // reason for it to be running.  Being on the top is a
15808                        // special state, meaning you are specifically running
15809                        // for the current top app.  If the process is already
15810                        // running in the background for some other reason, it
15811                        // is more important to continue considering it to be
15812                        // in the background state.
15813                        mayBeTop = true;
15814                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15815                    } else {
15816                        // Special handling for above-top states (persistent
15817                        // processes).  These should not bring the current process
15818                        // into the top state, since they are not on top.  Instead
15819                        // give them the best state after that.
15820                        clientProcState =
15821                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15822                    }
15823                }
15824                if (procState > clientProcState) {
15825                    procState = clientProcState;
15826                }
15827                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15828                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15829                }
15830            }
15831            // If the provider has external (non-framework) process
15832            // dependencies, ensure that its adjustment is at least
15833            // FOREGROUND_APP_ADJ.
15834            if (cpr.hasExternalProcessHandles()) {
15835                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15836                    adj = ProcessList.FOREGROUND_APP_ADJ;
15837                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15838                    app.cached = false;
15839                    app.adjType = "provider";
15840                    app.adjTarget = cpr.name;
15841                }
15842                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15843                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15844                }
15845            }
15846        }
15847
15848        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15849            // A client of one of our services or providers is in the top state.  We
15850            // *may* want to be in the top state, but not if we are already running in
15851            // the background for some other reason.  For the decision here, we are going
15852            // to pick out a few specific states that we want to remain in when a client
15853            // is top (states that tend to be longer-term) and otherwise allow it to go
15854            // to the top state.
15855            switch (procState) {
15856                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15857                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15858                case ActivityManager.PROCESS_STATE_SERVICE:
15859                    // These all are longer-term states, so pull them up to the top
15860                    // of the background states, but not all the way to the top state.
15861                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15862                    break;
15863                default:
15864                    // Otherwise, top is a better choice, so take it.
15865                    procState = ActivityManager.PROCESS_STATE_TOP;
15866                    break;
15867            }
15868        }
15869
15870        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15871            if (app.hasClientActivities) {
15872                // This is a cached process, but with client activities.  Mark it so.
15873                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15874                app.adjType = "cch-client-act";
15875            } else if (app.treatLikeActivity) {
15876                // This is a cached process, but somebody wants us to treat it like it has
15877                // an activity, okay!
15878                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15879                app.adjType = "cch-as-act";
15880            }
15881        }
15882
15883        if (adj == ProcessList.SERVICE_ADJ) {
15884            if (doingAll) {
15885                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15886                mNewNumServiceProcs++;
15887                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15888                if (!app.serviceb) {
15889                    // This service isn't far enough down on the LRU list to
15890                    // normally be a B service, but if we are low on RAM and it
15891                    // is large we want to force it down since we would prefer to
15892                    // keep launcher over it.
15893                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15894                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15895                        app.serviceHighRam = true;
15896                        app.serviceb = true;
15897                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15898                    } else {
15899                        mNewNumAServiceProcs++;
15900                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15901                    }
15902                } else {
15903                    app.serviceHighRam = false;
15904                }
15905            }
15906            if (app.serviceb) {
15907                adj = ProcessList.SERVICE_B_ADJ;
15908            }
15909        }
15910
15911        app.curRawAdj = adj;
15912
15913        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15914        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15915        if (adj > app.maxAdj) {
15916            adj = app.maxAdj;
15917            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15918                schedGroup = Process.THREAD_GROUP_DEFAULT;
15919            }
15920        }
15921
15922        // Do final modification to adj.  Everything we do between here and applying
15923        // the final setAdj must be done in this function, because we will also use
15924        // it when computing the final cached adj later.  Note that we don't need to
15925        // worry about this for max adj above, since max adj will always be used to
15926        // keep it out of the cached vaues.
15927        app.curAdj = app.modifyRawOomAdj(adj);
15928        app.curSchedGroup = schedGroup;
15929        app.curProcState = procState;
15930        app.foregroundActivities = foregroundActivities;
15931
15932        return app.curRawAdj;
15933    }
15934
15935    /**
15936     * Schedule PSS collection of a process.
15937     */
15938    void requestPssLocked(ProcessRecord proc, int procState) {
15939        if (mPendingPssProcesses.contains(proc)) {
15940            return;
15941        }
15942        if (mPendingPssProcesses.size() == 0) {
15943            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15944        }
15945        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15946        proc.pssProcState = procState;
15947        mPendingPssProcesses.add(proc);
15948    }
15949
15950    /**
15951     * Schedule PSS collection of all processes.
15952     */
15953    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15954        if (!always) {
15955            if (now < (mLastFullPssTime +
15956                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15957                return;
15958            }
15959        }
15960        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15961        mLastFullPssTime = now;
15962        mFullPssPending = true;
15963        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15964        mPendingPssProcesses.clear();
15965        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15966            ProcessRecord app = mLruProcesses.get(i);
15967            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15968                app.pssProcState = app.setProcState;
15969                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15970                        isSleeping(), now);
15971                mPendingPssProcesses.add(app);
15972            }
15973        }
15974        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15975    }
15976
15977    /**
15978     * Ask a given process to GC right now.
15979     */
15980    final void performAppGcLocked(ProcessRecord app) {
15981        try {
15982            app.lastRequestedGc = SystemClock.uptimeMillis();
15983            if (app.thread != null) {
15984                if (app.reportLowMemory) {
15985                    app.reportLowMemory = false;
15986                    app.thread.scheduleLowMemory();
15987                } else {
15988                    app.thread.processInBackground();
15989                }
15990            }
15991        } catch (Exception e) {
15992            // whatever.
15993        }
15994    }
15995
15996    /**
15997     * Returns true if things are idle enough to perform GCs.
15998     */
15999    private final boolean canGcNowLocked() {
16000        boolean processingBroadcasts = false;
16001        for (BroadcastQueue q : mBroadcastQueues) {
16002            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16003                processingBroadcasts = true;
16004            }
16005        }
16006        return !processingBroadcasts
16007                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16008    }
16009
16010    /**
16011     * Perform GCs on all processes that are waiting for it, but only
16012     * if things are idle.
16013     */
16014    final void performAppGcsLocked() {
16015        final int N = mProcessesToGc.size();
16016        if (N <= 0) {
16017            return;
16018        }
16019        if (canGcNowLocked()) {
16020            while (mProcessesToGc.size() > 0) {
16021                ProcessRecord proc = mProcessesToGc.remove(0);
16022                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16023                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16024                            <= SystemClock.uptimeMillis()) {
16025                        // To avoid spamming the system, we will GC processes one
16026                        // at a time, waiting a few seconds between each.
16027                        performAppGcLocked(proc);
16028                        scheduleAppGcsLocked();
16029                        return;
16030                    } else {
16031                        // It hasn't been long enough since we last GCed this
16032                        // process...  put it in the list to wait for its time.
16033                        addProcessToGcListLocked(proc);
16034                        break;
16035                    }
16036                }
16037            }
16038
16039            scheduleAppGcsLocked();
16040        }
16041    }
16042
16043    /**
16044     * If all looks good, perform GCs on all processes waiting for them.
16045     */
16046    final void performAppGcsIfAppropriateLocked() {
16047        if (canGcNowLocked()) {
16048            performAppGcsLocked();
16049            return;
16050        }
16051        // Still not idle, wait some more.
16052        scheduleAppGcsLocked();
16053    }
16054
16055    /**
16056     * Schedule the execution of all pending app GCs.
16057     */
16058    final void scheduleAppGcsLocked() {
16059        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16060
16061        if (mProcessesToGc.size() > 0) {
16062            // Schedule a GC for the time to the next process.
16063            ProcessRecord proc = mProcessesToGc.get(0);
16064            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16065
16066            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16067            long now = SystemClock.uptimeMillis();
16068            if (when < (now+GC_TIMEOUT)) {
16069                when = now + GC_TIMEOUT;
16070            }
16071            mHandler.sendMessageAtTime(msg, when);
16072        }
16073    }
16074
16075    /**
16076     * Add a process to the array of processes waiting to be GCed.  Keeps the
16077     * list in sorted order by the last GC time.  The process can't already be
16078     * on the list.
16079     */
16080    final void addProcessToGcListLocked(ProcessRecord proc) {
16081        boolean added = false;
16082        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16083            if (mProcessesToGc.get(i).lastRequestedGc <
16084                    proc.lastRequestedGc) {
16085                added = true;
16086                mProcessesToGc.add(i+1, proc);
16087                break;
16088            }
16089        }
16090        if (!added) {
16091            mProcessesToGc.add(0, proc);
16092        }
16093    }
16094
16095    /**
16096     * Set up to ask a process to GC itself.  This will either do it
16097     * immediately, or put it on the list of processes to gc the next
16098     * time things are idle.
16099     */
16100    final void scheduleAppGcLocked(ProcessRecord app) {
16101        long now = SystemClock.uptimeMillis();
16102        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16103            return;
16104        }
16105        if (!mProcessesToGc.contains(app)) {
16106            addProcessToGcListLocked(app);
16107            scheduleAppGcsLocked();
16108        }
16109    }
16110
16111    final void checkExcessivePowerUsageLocked(boolean doKills) {
16112        updateCpuStatsNow();
16113
16114        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16115        boolean doWakeKills = doKills;
16116        boolean doCpuKills = doKills;
16117        if (mLastPowerCheckRealtime == 0) {
16118            doWakeKills = false;
16119        }
16120        if (mLastPowerCheckUptime == 0) {
16121            doCpuKills = false;
16122        }
16123        if (stats.isScreenOn()) {
16124            doWakeKills = false;
16125        }
16126        final long curRealtime = SystemClock.elapsedRealtime();
16127        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16128        final long curUptime = SystemClock.uptimeMillis();
16129        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16130        mLastPowerCheckRealtime = curRealtime;
16131        mLastPowerCheckUptime = curUptime;
16132        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16133            doWakeKills = false;
16134        }
16135        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16136            doCpuKills = false;
16137        }
16138        int i = mLruProcesses.size();
16139        while (i > 0) {
16140            i--;
16141            ProcessRecord app = mLruProcesses.get(i);
16142            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16143                long wtime;
16144                synchronized (stats) {
16145                    wtime = stats.getProcessWakeTime(app.info.uid,
16146                            app.pid, curRealtime);
16147                }
16148                long wtimeUsed = wtime - app.lastWakeTime;
16149                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16150                if (DEBUG_POWER) {
16151                    StringBuilder sb = new StringBuilder(128);
16152                    sb.append("Wake for ");
16153                    app.toShortString(sb);
16154                    sb.append(": over ");
16155                    TimeUtils.formatDuration(realtimeSince, sb);
16156                    sb.append(" used ");
16157                    TimeUtils.formatDuration(wtimeUsed, sb);
16158                    sb.append(" (");
16159                    sb.append((wtimeUsed*100)/realtimeSince);
16160                    sb.append("%)");
16161                    Slog.i(TAG, sb.toString());
16162                    sb.setLength(0);
16163                    sb.append("CPU for ");
16164                    app.toShortString(sb);
16165                    sb.append(": over ");
16166                    TimeUtils.formatDuration(uptimeSince, sb);
16167                    sb.append(" used ");
16168                    TimeUtils.formatDuration(cputimeUsed, sb);
16169                    sb.append(" (");
16170                    sb.append((cputimeUsed*100)/uptimeSince);
16171                    sb.append("%)");
16172                    Slog.i(TAG, sb.toString());
16173                }
16174                // If a process has held a wake lock for more
16175                // than 50% of the time during this period,
16176                // that sounds bad.  Kill!
16177                if (doWakeKills && realtimeSince > 0
16178                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16179                    synchronized (stats) {
16180                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16181                                realtimeSince, wtimeUsed);
16182                    }
16183                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16184                            + " during " + realtimeSince);
16185                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16186                } else if (doCpuKills && uptimeSince > 0
16187                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16188                    synchronized (stats) {
16189                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16190                                uptimeSince, cputimeUsed);
16191                    }
16192                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16193                            + " during " + uptimeSince);
16194                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16195                } else {
16196                    app.lastWakeTime = wtime;
16197                    app.lastCpuTime = app.curCpuTime;
16198                }
16199            }
16200        }
16201    }
16202
16203    private final boolean applyOomAdjLocked(ProcessRecord app,
16204            ProcessRecord TOP_APP, boolean doingAll, long now) {
16205        boolean success = true;
16206
16207        if (app.curRawAdj != app.setRawAdj) {
16208            app.setRawAdj = app.curRawAdj;
16209        }
16210
16211        int changes = 0;
16212
16213        if (app.curAdj != app.setAdj) {
16214            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16215            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16216                TAG, "Set " + app.pid + " " + app.processName +
16217                " adj " + app.curAdj + ": " + app.adjType);
16218            app.setAdj = app.curAdj;
16219        }
16220
16221        if (app.setSchedGroup != app.curSchedGroup) {
16222            app.setSchedGroup = app.curSchedGroup;
16223            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16224                    "Setting process group of " + app.processName
16225                    + " to " + app.curSchedGroup);
16226            if (app.waitingToKill != null &&
16227                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16228                killUnneededProcessLocked(app, app.waitingToKill);
16229                success = false;
16230            } else {
16231                if (true) {
16232                    long oldId = Binder.clearCallingIdentity();
16233                    try {
16234                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16235                    } catch (Exception e) {
16236                        Slog.w(TAG, "Failed setting process group of " + app.pid
16237                                + " to " + app.curSchedGroup);
16238                        e.printStackTrace();
16239                    } finally {
16240                        Binder.restoreCallingIdentity(oldId);
16241                    }
16242                } else {
16243                    if (app.thread != null) {
16244                        try {
16245                            app.thread.setSchedulingGroup(app.curSchedGroup);
16246                        } catch (RemoteException e) {
16247                        }
16248                    }
16249                }
16250                Process.setSwappiness(app.pid,
16251                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16252            }
16253        }
16254        if (app.repForegroundActivities != app.foregroundActivities) {
16255            app.repForegroundActivities = app.foregroundActivities;
16256            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16257        }
16258        if (app.repProcState != app.curProcState) {
16259            app.repProcState = app.curProcState;
16260            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16261            if (app.thread != null) {
16262                try {
16263                    if (false) {
16264                        //RuntimeException h = new RuntimeException("here");
16265                        Slog.i(TAG, "Sending new process state " + app.repProcState
16266                                + " to " + app /*, h*/);
16267                    }
16268                    app.thread.setProcessState(app.repProcState);
16269                } catch (RemoteException e) {
16270                }
16271            }
16272        }
16273        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16274                app.setProcState)) {
16275            app.lastStateTime = now;
16276            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16277                    isSleeping(), now);
16278            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16279                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16280                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16281                    + (app.nextPssTime-now) + ": " + app);
16282        } else {
16283            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16284                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16285                requestPssLocked(app, app.setProcState);
16286                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16287                        isSleeping(), now);
16288            } else if (false && DEBUG_PSS) {
16289                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16290            }
16291        }
16292        if (app.setProcState != app.curProcState) {
16293            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16294                    "Proc state change of " + app.processName
16295                    + " to " + app.curProcState);
16296            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16297            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16298            if (setImportant && !curImportant) {
16299                // This app is no longer something we consider important enough to allow to
16300                // use arbitrary amounts of battery power.  Note
16301                // its current wake lock time to later know to kill it if
16302                // it is not behaving well.
16303                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16304                synchronized (stats) {
16305                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16306                            app.pid, SystemClock.elapsedRealtime());
16307                }
16308                app.lastCpuTime = app.curCpuTime;
16309
16310            }
16311            app.setProcState = app.curProcState;
16312            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16313                app.notCachedSinceIdle = false;
16314            }
16315            if (!doingAll) {
16316                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16317            } else {
16318                app.procStateChanged = true;
16319            }
16320        }
16321
16322        if (changes != 0) {
16323            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16324            int i = mPendingProcessChanges.size()-1;
16325            ProcessChangeItem item = null;
16326            while (i >= 0) {
16327                item = mPendingProcessChanges.get(i);
16328                if (item.pid == app.pid) {
16329                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16330                    break;
16331                }
16332                i--;
16333            }
16334            if (i < 0) {
16335                // No existing item in pending changes; need a new one.
16336                final int NA = mAvailProcessChanges.size();
16337                if (NA > 0) {
16338                    item = mAvailProcessChanges.remove(NA-1);
16339                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16340                } else {
16341                    item = new ProcessChangeItem();
16342                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16343                }
16344                item.changes = 0;
16345                item.pid = app.pid;
16346                item.uid = app.info.uid;
16347                if (mPendingProcessChanges.size() == 0) {
16348                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16349                            "*** Enqueueing dispatch processes changed!");
16350                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16351                }
16352                mPendingProcessChanges.add(item);
16353            }
16354            item.changes |= changes;
16355            item.processState = app.repProcState;
16356            item.foregroundActivities = app.repForegroundActivities;
16357            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16358                    + Integer.toHexString(System.identityHashCode(item))
16359                    + " " + app.toShortString() + ": changes=" + item.changes
16360                    + " procState=" + item.processState
16361                    + " foreground=" + item.foregroundActivities
16362                    + " type=" + app.adjType + " source=" + app.adjSource
16363                    + " target=" + app.adjTarget);
16364        }
16365
16366        return success;
16367    }
16368
16369    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16370        if (proc.thread != null) {
16371            if (proc.baseProcessTracker != null) {
16372                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16373            }
16374            if (proc.repProcState >= 0) {
16375                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16376                        proc.repProcState);
16377            }
16378        }
16379    }
16380
16381    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16382            ProcessRecord TOP_APP, boolean doingAll, long now) {
16383        if (app.thread == null) {
16384            return false;
16385        }
16386
16387        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16388
16389        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16390    }
16391
16392    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16393            boolean oomAdj) {
16394        if (isForeground != proc.foregroundServices) {
16395            proc.foregroundServices = isForeground;
16396            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16397                    proc.info.uid);
16398            if (isForeground) {
16399                if (curProcs == null) {
16400                    curProcs = new ArrayList<ProcessRecord>();
16401                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16402                }
16403                if (!curProcs.contains(proc)) {
16404                    curProcs.add(proc);
16405                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16406                            proc.info.packageName, proc.info.uid);
16407                }
16408            } else {
16409                if (curProcs != null) {
16410                    if (curProcs.remove(proc)) {
16411                        mBatteryStatsService.noteEvent(
16412                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16413                                proc.info.packageName, proc.info.uid);
16414                        if (curProcs.size() <= 0) {
16415                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16416                        }
16417                    }
16418                }
16419            }
16420            if (oomAdj) {
16421                updateOomAdjLocked();
16422            }
16423        }
16424    }
16425
16426    private final ActivityRecord resumedAppLocked() {
16427        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16428        String pkg;
16429        int uid;
16430        if (act != null) {
16431            pkg = act.packageName;
16432            uid = act.info.applicationInfo.uid;
16433        } else {
16434            pkg = null;
16435            uid = -1;
16436        }
16437        // Has the UID or resumed package name changed?
16438        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16439                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16440            if (mCurResumedPackage != null) {
16441                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16442                        mCurResumedPackage, mCurResumedUid);
16443            }
16444            mCurResumedPackage = pkg;
16445            mCurResumedUid = uid;
16446            if (mCurResumedPackage != null) {
16447                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16448                        mCurResumedPackage, mCurResumedUid);
16449            }
16450        }
16451        return act;
16452    }
16453
16454    final boolean updateOomAdjLocked(ProcessRecord app) {
16455        final ActivityRecord TOP_ACT = resumedAppLocked();
16456        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16457        final boolean wasCached = app.cached;
16458
16459        mAdjSeq++;
16460
16461        // This is the desired cached adjusment we want to tell it to use.
16462        // If our app is currently cached, we know it, and that is it.  Otherwise,
16463        // we don't know it yet, and it needs to now be cached we will then
16464        // need to do a complete oom adj.
16465        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16466                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16467        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16468                SystemClock.uptimeMillis());
16469        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16470            // Changed to/from cached state, so apps after it in the LRU
16471            // list may also be changed.
16472            updateOomAdjLocked();
16473        }
16474        return success;
16475    }
16476
16477    final void updateOomAdjLocked() {
16478        final ActivityRecord TOP_ACT = resumedAppLocked();
16479        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16480        final long now = SystemClock.uptimeMillis();
16481        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16482        final int N = mLruProcesses.size();
16483
16484        if (false) {
16485            RuntimeException e = new RuntimeException();
16486            e.fillInStackTrace();
16487            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16488        }
16489
16490        mAdjSeq++;
16491        mNewNumServiceProcs = 0;
16492        mNewNumAServiceProcs = 0;
16493
16494        final int emptyProcessLimit;
16495        final int cachedProcessLimit;
16496        if (mProcessLimit <= 0) {
16497            emptyProcessLimit = cachedProcessLimit = 0;
16498        } else if (mProcessLimit == 1) {
16499            emptyProcessLimit = 1;
16500            cachedProcessLimit = 0;
16501        } else {
16502            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16503            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16504        }
16505
16506        // Let's determine how many processes we have running vs.
16507        // how many slots we have for background processes; we may want
16508        // to put multiple processes in a slot of there are enough of
16509        // them.
16510        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16511                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16512        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16513        if (numEmptyProcs > cachedProcessLimit) {
16514            // If there are more empty processes than our limit on cached
16515            // processes, then use the cached process limit for the factor.
16516            // This ensures that the really old empty processes get pushed
16517            // down to the bottom, so if we are running low on memory we will
16518            // have a better chance at keeping around more cached processes
16519            // instead of a gazillion empty processes.
16520            numEmptyProcs = cachedProcessLimit;
16521        }
16522        int emptyFactor = numEmptyProcs/numSlots;
16523        if (emptyFactor < 1) emptyFactor = 1;
16524        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16525        if (cachedFactor < 1) cachedFactor = 1;
16526        int stepCached = 0;
16527        int stepEmpty = 0;
16528        int numCached = 0;
16529        int numEmpty = 0;
16530        int numTrimming = 0;
16531
16532        mNumNonCachedProcs = 0;
16533        mNumCachedHiddenProcs = 0;
16534
16535        // First update the OOM adjustment for each of the
16536        // application processes based on their current state.
16537        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16538        int nextCachedAdj = curCachedAdj+1;
16539        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16540        int nextEmptyAdj = curEmptyAdj+2;
16541        for (int i=N-1; i>=0; i--) {
16542            ProcessRecord app = mLruProcesses.get(i);
16543            if (!app.killedByAm && app.thread != null) {
16544                app.procStateChanged = false;
16545                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16546
16547                // If we haven't yet assigned the final cached adj
16548                // to the process, do that now.
16549                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16550                    switch (app.curProcState) {
16551                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16552                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16553                            // This process is a cached process holding activities...
16554                            // assign it the next cached value for that type, and then
16555                            // step that cached level.
16556                            app.curRawAdj = curCachedAdj;
16557                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16558                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16559                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16560                                    + ")");
16561                            if (curCachedAdj != nextCachedAdj) {
16562                                stepCached++;
16563                                if (stepCached >= cachedFactor) {
16564                                    stepCached = 0;
16565                                    curCachedAdj = nextCachedAdj;
16566                                    nextCachedAdj += 2;
16567                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16568                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16569                                    }
16570                                }
16571                            }
16572                            break;
16573                        default:
16574                            // For everything else, assign next empty cached process
16575                            // level and bump that up.  Note that this means that
16576                            // long-running services that have dropped down to the
16577                            // cached level will be treated as empty (since their process
16578                            // state is still as a service), which is what we want.
16579                            app.curRawAdj = curEmptyAdj;
16580                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16581                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16582                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16583                                    + ")");
16584                            if (curEmptyAdj != nextEmptyAdj) {
16585                                stepEmpty++;
16586                                if (stepEmpty >= emptyFactor) {
16587                                    stepEmpty = 0;
16588                                    curEmptyAdj = nextEmptyAdj;
16589                                    nextEmptyAdj += 2;
16590                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16591                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16592                                    }
16593                                }
16594                            }
16595                            break;
16596                    }
16597                }
16598
16599                applyOomAdjLocked(app, TOP_APP, true, now);
16600
16601                // Count the number of process types.
16602                switch (app.curProcState) {
16603                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16604                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16605                        mNumCachedHiddenProcs++;
16606                        numCached++;
16607                        if (numCached > cachedProcessLimit) {
16608                            killUnneededProcessLocked(app, "cached #" + numCached);
16609                        }
16610                        break;
16611                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16612                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16613                                && app.lastActivityTime < oldTime) {
16614                            killUnneededProcessLocked(app, "empty for "
16615                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16616                                    / 1000) + "s");
16617                        } else {
16618                            numEmpty++;
16619                            if (numEmpty > emptyProcessLimit) {
16620                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16621                            }
16622                        }
16623                        break;
16624                    default:
16625                        mNumNonCachedProcs++;
16626                        break;
16627                }
16628
16629                if (app.isolated && app.services.size() <= 0) {
16630                    // If this is an isolated process, and there are no
16631                    // services running in it, then the process is no longer
16632                    // needed.  We agressively kill these because we can by
16633                    // definition not re-use the same process again, and it is
16634                    // good to avoid having whatever code was running in them
16635                    // left sitting around after no longer needed.
16636                    killUnneededProcessLocked(app, "isolated not needed");
16637                }
16638
16639                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16640                        && !app.killedByAm) {
16641                    numTrimming++;
16642                }
16643            }
16644        }
16645
16646        mNumServiceProcs = mNewNumServiceProcs;
16647
16648        // Now determine the memory trimming level of background processes.
16649        // Unfortunately we need to start at the back of the list to do this
16650        // properly.  We only do this if the number of background apps we
16651        // are managing to keep around is less than half the maximum we desire;
16652        // if we are keeping a good number around, we'll let them use whatever
16653        // memory they want.
16654        final int numCachedAndEmpty = numCached + numEmpty;
16655        int memFactor;
16656        if (numCached <= ProcessList.TRIM_CACHED_APPS
16657                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16658            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16659                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16660            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16661                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16662            } else {
16663                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16664            }
16665        } else {
16666            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16667        }
16668        // We always allow the memory level to go up (better).  We only allow it to go
16669        // down if we are in a state where that is allowed, *and* the total number of processes
16670        // has gone down since last time.
16671        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16672                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16673                + " last=" + mLastNumProcesses);
16674        if (memFactor > mLastMemoryLevel) {
16675            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16676                memFactor = mLastMemoryLevel;
16677                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16678            }
16679        }
16680        mLastMemoryLevel = memFactor;
16681        mLastNumProcesses = mLruProcesses.size();
16682        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16683        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16684        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16685            if (mLowRamStartTime == 0) {
16686                mLowRamStartTime = now;
16687            }
16688            int step = 0;
16689            int fgTrimLevel;
16690            switch (memFactor) {
16691                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16692                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16693                    break;
16694                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16695                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16696                    break;
16697                default:
16698                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16699                    break;
16700            }
16701            int factor = numTrimming/3;
16702            int minFactor = 2;
16703            if (mHomeProcess != null) minFactor++;
16704            if (mPreviousProcess != null) minFactor++;
16705            if (factor < minFactor) factor = minFactor;
16706            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16707            for (int i=N-1; i>=0; i--) {
16708                ProcessRecord app = mLruProcesses.get(i);
16709                if (allChanged || app.procStateChanged) {
16710                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16711                    app.procStateChanged = false;
16712                }
16713                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16714                        && !app.killedByAm) {
16715                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16716                        try {
16717                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16718                                    "Trimming memory of " + app.processName
16719                                    + " to " + curLevel);
16720                            app.thread.scheduleTrimMemory(curLevel);
16721                        } catch (RemoteException e) {
16722                        }
16723                        if (false) {
16724                            // For now we won't do this; our memory trimming seems
16725                            // to be good enough at this point that destroying
16726                            // activities causes more harm than good.
16727                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16728                                    && app != mHomeProcess && app != mPreviousProcess) {
16729                                // Need to do this on its own message because the stack may not
16730                                // be in a consistent state at this point.
16731                                // For these apps we will also finish their activities
16732                                // to help them free memory.
16733                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16734                            }
16735                        }
16736                    }
16737                    app.trimMemoryLevel = curLevel;
16738                    step++;
16739                    if (step >= factor) {
16740                        step = 0;
16741                        switch (curLevel) {
16742                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16743                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16744                                break;
16745                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16746                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16747                                break;
16748                        }
16749                    }
16750                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16751                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16752                            && app.thread != null) {
16753                        try {
16754                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16755                                    "Trimming memory of heavy-weight " + app.processName
16756                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16757                            app.thread.scheduleTrimMemory(
16758                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16759                        } catch (RemoteException e) {
16760                        }
16761                    }
16762                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16763                } else {
16764                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16765                            || app.systemNoUi) && app.pendingUiClean) {
16766                        // If this application is now in the background and it
16767                        // had done UI, then give it the special trim level to
16768                        // have it free UI resources.
16769                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16770                        if (app.trimMemoryLevel < level && app.thread != null) {
16771                            try {
16772                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16773                                        "Trimming memory of bg-ui " + app.processName
16774                                        + " to " + level);
16775                                app.thread.scheduleTrimMemory(level);
16776                            } catch (RemoteException e) {
16777                            }
16778                        }
16779                        app.pendingUiClean = false;
16780                    }
16781                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16782                        try {
16783                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16784                                    "Trimming memory of fg " + app.processName
16785                                    + " to " + fgTrimLevel);
16786                            app.thread.scheduleTrimMemory(fgTrimLevel);
16787                        } catch (RemoteException e) {
16788                        }
16789                    }
16790                    app.trimMemoryLevel = fgTrimLevel;
16791                }
16792            }
16793        } else {
16794            if (mLowRamStartTime != 0) {
16795                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16796                mLowRamStartTime = 0;
16797            }
16798            for (int i=N-1; i>=0; i--) {
16799                ProcessRecord app = mLruProcesses.get(i);
16800                if (allChanged || app.procStateChanged) {
16801                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16802                    app.procStateChanged = false;
16803                }
16804                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16805                        || app.systemNoUi) && app.pendingUiClean) {
16806                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16807                            && app.thread != null) {
16808                        try {
16809                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16810                                    "Trimming memory of ui hidden " + app.processName
16811                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16812                            app.thread.scheduleTrimMemory(
16813                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16814                        } catch (RemoteException e) {
16815                        }
16816                    }
16817                    app.pendingUiClean = false;
16818                }
16819                app.trimMemoryLevel = 0;
16820            }
16821        }
16822
16823        if (mAlwaysFinishActivities) {
16824            // Need to do this on its own message because the stack may not
16825            // be in a consistent state at this point.
16826            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16827        }
16828
16829        if (allChanged) {
16830            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16831        }
16832
16833        if (mProcessStats.shouldWriteNowLocked(now)) {
16834            mHandler.post(new Runnable() {
16835                @Override public void run() {
16836                    synchronized (ActivityManagerService.this) {
16837                        mProcessStats.writeStateAsyncLocked();
16838                    }
16839                }
16840            });
16841        }
16842
16843        if (DEBUG_OOM_ADJ) {
16844            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16845        }
16846    }
16847
16848    final void trimApplications() {
16849        synchronized (this) {
16850            int i;
16851
16852            // First remove any unused application processes whose package
16853            // has been removed.
16854            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16855                final ProcessRecord app = mRemovedProcesses.get(i);
16856                if (app.activities.size() == 0
16857                        && app.curReceiver == null && app.services.size() == 0) {
16858                    Slog.i(
16859                        TAG, "Exiting empty application process "
16860                        + app.processName + " ("
16861                        + (app.thread != null ? app.thread.asBinder() : null)
16862                        + ")\n");
16863                    if (app.pid > 0 && app.pid != MY_PID) {
16864                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16865                                app.processName, app.setAdj, "empty");
16866                        app.killedByAm = true;
16867                        Process.killProcessQuiet(app.pid);
16868                        Process.killProcessGroup(app.info.uid, app.pid);
16869                    } else {
16870                        try {
16871                            app.thread.scheduleExit();
16872                        } catch (Exception e) {
16873                            // Ignore exceptions.
16874                        }
16875                    }
16876                    cleanUpApplicationRecordLocked(app, false, true, -1);
16877                    mRemovedProcesses.remove(i);
16878
16879                    if (app.persistent) {
16880                        addAppLocked(app.info, false, null /* ABI override */);
16881                    }
16882                }
16883            }
16884
16885            // Now update the oom adj for all processes.
16886            updateOomAdjLocked();
16887        }
16888    }
16889
16890    /** This method sends the specified signal to each of the persistent apps */
16891    public void signalPersistentProcesses(int sig) throws RemoteException {
16892        if (sig != Process.SIGNAL_USR1) {
16893            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16894        }
16895
16896        synchronized (this) {
16897            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16898                    != PackageManager.PERMISSION_GRANTED) {
16899                throw new SecurityException("Requires permission "
16900                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16901            }
16902
16903            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16904                ProcessRecord r = mLruProcesses.get(i);
16905                if (r.thread != null && r.persistent) {
16906                    Process.sendSignal(r.pid, sig);
16907                }
16908            }
16909        }
16910    }
16911
16912    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16913        if (proc == null || proc == mProfileProc) {
16914            proc = mProfileProc;
16915            path = mProfileFile;
16916            profileType = mProfileType;
16917            clearProfilerLocked();
16918        }
16919        if (proc == null) {
16920            return;
16921        }
16922        try {
16923            proc.thread.profilerControl(false, path, null, profileType);
16924        } catch (RemoteException e) {
16925            throw new IllegalStateException("Process disappeared");
16926        }
16927    }
16928
16929    private void clearProfilerLocked() {
16930        if (mProfileFd != null) {
16931            try {
16932                mProfileFd.close();
16933            } catch (IOException e) {
16934            }
16935        }
16936        mProfileApp = null;
16937        mProfileProc = null;
16938        mProfileFile = null;
16939        mProfileType = 0;
16940        mAutoStopProfiler = false;
16941    }
16942
16943    public boolean profileControl(String process, int userId, boolean start,
16944            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16945
16946        try {
16947            synchronized (this) {
16948                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16949                // its own permission.
16950                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16951                        != PackageManager.PERMISSION_GRANTED) {
16952                    throw new SecurityException("Requires permission "
16953                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16954                }
16955
16956                if (start && fd == null) {
16957                    throw new IllegalArgumentException("null fd");
16958                }
16959
16960                ProcessRecord proc = null;
16961                if (process != null) {
16962                    proc = findProcessLocked(process, userId, "profileControl");
16963                }
16964
16965                if (start && (proc == null || proc.thread == null)) {
16966                    throw new IllegalArgumentException("Unknown process: " + process);
16967                }
16968
16969                if (start) {
16970                    stopProfilerLocked(null, null, 0);
16971                    setProfileApp(proc.info, proc.processName, path, fd, false);
16972                    mProfileProc = proc;
16973                    mProfileType = profileType;
16974                    try {
16975                        fd = fd.dup();
16976                    } catch (IOException e) {
16977                        fd = null;
16978                    }
16979                    proc.thread.profilerControl(start, path, fd, profileType);
16980                    fd = null;
16981                    mProfileFd = null;
16982                } else {
16983                    stopProfilerLocked(proc, path, profileType);
16984                    if (fd != null) {
16985                        try {
16986                            fd.close();
16987                        } catch (IOException e) {
16988                        }
16989                    }
16990                }
16991
16992                return true;
16993            }
16994        } catch (RemoteException e) {
16995            throw new IllegalStateException("Process disappeared");
16996        } finally {
16997            if (fd != null) {
16998                try {
16999                    fd.close();
17000                } catch (IOException e) {
17001                }
17002            }
17003        }
17004    }
17005
17006    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17007        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17008                userId, true, ALLOW_FULL_ONLY, callName, null);
17009        ProcessRecord proc = null;
17010        try {
17011            int pid = Integer.parseInt(process);
17012            synchronized (mPidsSelfLocked) {
17013                proc = mPidsSelfLocked.get(pid);
17014            }
17015        } catch (NumberFormatException e) {
17016        }
17017
17018        if (proc == null) {
17019            ArrayMap<String, SparseArray<ProcessRecord>> all
17020                    = mProcessNames.getMap();
17021            SparseArray<ProcessRecord> procs = all.get(process);
17022            if (procs != null && procs.size() > 0) {
17023                proc = procs.valueAt(0);
17024                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17025                    for (int i=1; i<procs.size(); i++) {
17026                        ProcessRecord thisProc = procs.valueAt(i);
17027                        if (thisProc.userId == userId) {
17028                            proc = thisProc;
17029                            break;
17030                        }
17031                    }
17032                }
17033            }
17034        }
17035
17036        return proc;
17037    }
17038
17039    public boolean dumpHeap(String process, int userId, boolean managed,
17040            String path, ParcelFileDescriptor fd) throws RemoteException {
17041
17042        try {
17043            synchronized (this) {
17044                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17045                // its own permission (same as profileControl).
17046                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17047                        != PackageManager.PERMISSION_GRANTED) {
17048                    throw new SecurityException("Requires permission "
17049                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17050                }
17051
17052                if (fd == null) {
17053                    throw new IllegalArgumentException("null fd");
17054                }
17055
17056                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17057                if (proc == null || proc.thread == null) {
17058                    throw new IllegalArgumentException("Unknown process: " + process);
17059                }
17060
17061                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17062                if (!isDebuggable) {
17063                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17064                        throw new SecurityException("Process not debuggable: " + proc);
17065                    }
17066                }
17067
17068                proc.thread.dumpHeap(managed, path, fd);
17069                fd = null;
17070                return true;
17071            }
17072        } catch (RemoteException e) {
17073            throw new IllegalStateException("Process disappeared");
17074        } finally {
17075            if (fd != null) {
17076                try {
17077                    fd.close();
17078                } catch (IOException e) {
17079                }
17080            }
17081        }
17082    }
17083
17084    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17085    public void monitor() {
17086        synchronized (this) { }
17087    }
17088
17089    void onCoreSettingsChange(Bundle settings) {
17090        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17091            ProcessRecord processRecord = mLruProcesses.get(i);
17092            try {
17093                if (processRecord.thread != null) {
17094                    processRecord.thread.setCoreSettings(settings);
17095                }
17096            } catch (RemoteException re) {
17097                /* ignore */
17098            }
17099        }
17100    }
17101
17102    // Multi-user methods
17103
17104    /**
17105     * Start user, if its not already running, but don't bring it to foreground.
17106     */
17107    @Override
17108    public boolean startUserInBackground(final int userId) {
17109        return startUser(userId, /* foreground */ false);
17110    }
17111
17112    /**
17113     * Refreshes the list of users related to the current user when either a
17114     * user switch happens or when a new related user is started in the
17115     * background.
17116     */
17117    private void updateCurrentProfileIdsLocked() {
17118        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17119                mCurrentUserId, false /* enabledOnly */);
17120        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17121        for (int i = 0; i < currentProfileIds.length; i++) {
17122            currentProfileIds[i] = profiles.get(i).id;
17123        }
17124        mCurrentProfileIds = currentProfileIds;
17125
17126        synchronized (mUserProfileGroupIdsSelfLocked) {
17127            mUserProfileGroupIdsSelfLocked.clear();
17128            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17129            for (int i = 0; i < users.size(); i++) {
17130                UserInfo user = users.get(i);
17131                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17132                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17133                }
17134            }
17135        }
17136    }
17137
17138    private Set getProfileIdsLocked(int userId) {
17139        Set userIds = new HashSet<Integer>();
17140        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17141                userId, false /* enabledOnly */);
17142        for (UserInfo user : profiles) {
17143            userIds.add(Integer.valueOf(user.id));
17144        }
17145        return userIds;
17146    }
17147
17148    @Override
17149    public boolean switchUser(final int userId) {
17150        return startUser(userId, /* foregound */ true);
17151    }
17152
17153    private boolean startUser(final int userId, boolean foreground) {
17154        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17155                != PackageManager.PERMISSION_GRANTED) {
17156            String msg = "Permission Denial: switchUser() from pid="
17157                    + Binder.getCallingPid()
17158                    + ", uid=" + Binder.getCallingUid()
17159                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17160            Slog.w(TAG, msg);
17161            throw new SecurityException(msg);
17162        }
17163
17164        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17165
17166        final long ident = Binder.clearCallingIdentity();
17167        try {
17168            synchronized (this) {
17169                final int oldUserId = mCurrentUserId;
17170                if (oldUserId == userId) {
17171                    return true;
17172                }
17173
17174                mStackSupervisor.setLockTaskModeLocked(null, false);
17175
17176                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17177                if (userInfo == null) {
17178                    Slog.w(TAG, "No user info for user #" + userId);
17179                    return false;
17180                }
17181
17182                if (foreground) {
17183                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17184                            R.anim.screen_user_enter);
17185                }
17186
17187                boolean needStart = false;
17188
17189                // If the user we are switching to is not currently started, then
17190                // we need to start it now.
17191                if (mStartedUsers.get(userId) == null) {
17192                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17193                    updateStartedUserArrayLocked();
17194                    needStart = true;
17195                }
17196
17197                final Integer userIdInt = Integer.valueOf(userId);
17198                mUserLru.remove(userIdInt);
17199                mUserLru.add(userIdInt);
17200
17201                if (foreground) {
17202                    mCurrentUserId = userId;
17203                    updateCurrentProfileIdsLocked();
17204                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17205                    // Once the internal notion of the active user has switched, we lock the device
17206                    // with the option to show the user switcher on the keyguard.
17207                    mWindowManager.lockNow(null);
17208                } else {
17209                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17210                    updateCurrentProfileIdsLocked();
17211                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17212                    mUserLru.remove(currentUserIdInt);
17213                    mUserLru.add(currentUserIdInt);
17214                }
17215
17216                final UserStartedState uss = mStartedUsers.get(userId);
17217
17218                // Make sure user is in the started state.  If it is currently
17219                // stopping, we need to knock that off.
17220                if (uss.mState == UserStartedState.STATE_STOPPING) {
17221                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17222                    // so we can just fairly silently bring the user back from
17223                    // the almost-dead.
17224                    uss.mState = UserStartedState.STATE_RUNNING;
17225                    updateStartedUserArrayLocked();
17226                    needStart = true;
17227                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17228                    // This means ACTION_SHUTDOWN has been sent, so we will
17229                    // need to treat this as a new boot of the user.
17230                    uss.mState = UserStartedState.STATE_BOOTING;
17231                    updateStartedUserArrayLocked();
17232                    needStart = true;
17233                }
17234
17235                if (uss.mState == UserStartedState.STATE_BOOTING) {
17236                    // Booting up a new user, need to tell system services about it.
17237                    // Note that this is on the same handler as scheduling of broadcasts,
17238                    // which is important because it needs to go first.
17239                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17240                }
17241
17242                if (foreground) {
17243                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17244                            oldUserId));
17245                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17246                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17247                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17248                            oldUserId, userId, uss));
17249                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17250                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17251                }
17252
17253                if (needStart) {
17254                    // Send USER_STARTED broadcast
17255                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17256                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17257                            | Intent.FLAG_RECEIVER_FOREGROUND);
17258                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17259                    broadcastIntentLocked(null, null, intent,
17260                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17261                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17262                }
17263
17264                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17265                    if (userId != UserHandle.USER_OWNER) {
17266                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17267                        final ArrayList<ComponentName> doneReceivers
17268                                = new ArrayList<ComponentName>();
17269                        deliverPreBootCompleted(null, doneReceivers, userId);
17270
17271                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17272                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17273                        broadcastIntentLocked(null, null, intent, null,
17274                                new IIntentReceiver.Stub() {
17275                                    public void performReceive(Intent intent, int resultCode,
17276                                            String data, Bundle extras, boolean ordered,
17277                                            boolean sticky, int sendingUser) {
17278                                        userInitialized(uss, userId);
17279                                    }
17280                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17281                                true, false, MY_PID, Process.SYSTEM_UID,
17282                                userId);
17283                        uss.initializing = true;
17284                    } else {
17285                        getUserManagerLocked().makeInitialized(userInfo.id);
17286                    }
17287                }
17288
17289                if (foreground) {
17290                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17291                    if (homeInFront) {
17292                        startHomeActivityLocked(userId);
17293                    } else {
17294                        mStackSupervisor.resumeTopActivitiesLocked();
17295                    }
17296                    EventLogTags.writeAmSwitchUser(userId);
17297                    getUserManagerLocked().userForeground(userId);
17298                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17299                } else {
17300                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17301                }
17302
17303                if (needStart) {
17304                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17305                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17306                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17307                    broadcastIntentLocked(null, null, intent,
17308                            null, new IIntentReceiver.Stub() {
17309                                @Override
17310                                public void performReceive(Intent intent, int resultCode, String data,
17311                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17312                                        throws RemoteException {
17313                                }
17314                            }, 0, null, null,
17315                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17316                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17317                }
17318            }
17319        } finally {
17320            Binder.restoreCallingIdentity(ident);
17321        }
17322
17323        return true;
17324    }
17325
17326    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17327        long ident = Binder.clearCallingIdentity();
17328        try {
17329            Intent intent;
17330            if (oldUserId >= 0) {
17331                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17332                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17333                int count = profiles.size();
17334                for (int i = 0; i < count; i++) {
17335                    int profileUserId = profiles.get(i).id;
17336                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17337                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17338                            | Intent.FLAG_RECEIVER_FOREGROUND);
17339                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17340                    broadcastIntentLocked(null, null, intent,
17341                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17342                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17343                }
17344            }
17345            if (newUserId >= 0) {
17346                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17347                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17348                int count = profiles.size();
17349                for (int i = 0; i < count; i++) {
17350                    int profileUserId = profiles.get(i).id;
17351                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17352                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17353                            | Intent.FLAG_RECEIVER_FOREGROUND);
17354                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17355                    broadcastIntentLocked(null, null, intent,
17356                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17357                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17358                }
17359                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17360                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17361                        | Intent.FLAG_RECEIVER_FOREGROUND);
17362                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17363                broadcastIntentLocked(null, null, intent,
17364                        null, null, 0, null, null,
17365                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17366                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17367            }
17368        } finally {
17369            Binder.restoreCallingIdentity(ident);
17370        }
17371    }
17372
17373    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17374            final int newUserId) {
17375        final int N = mUserSwitchObservers.beginBroadcast();
17376        if (N > 0) {
17377            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17378                int mCount = 0;
17379                @Override
17380                public void sendResult(Bundle data) throws RemoteException {
17381                    synchronized (ActivityManagerService.this) {
17382                        if (mCurUserSwitchCallback == this) {
17383                            mCount++;
17384                            if (mCount == N) {
17385                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17386                            }
17387                        }
17388                    }
17389                }
17390            };
17391            synchronized (this) {
17392                uss.switching = true;
17393                mCurUserSwitchCallback = callback;
17394            }
17395            for (int i=0; i<N; i++) {
17396                try {
17397                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17398                            newUserId, callback);
17399                } catch (RemoteException e) {
17400                }
17401            }
17402        } else {
17403            synchronized (this) {
17404                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17405            }
17406        }
17407        mUserSwitchObservers.finishBroadcast();
17408    }
17409
17410    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17411        synchronized (this) {
17412            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17413            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17414        }
17415    }
17416
17417    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17418        mCurUserSwitchCallback = null;
17419        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17420        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17421                oldUserId, newUserId, uss));
17422    }
17423
17424    void userInitialized(UserStartedState uss, int newUserId) {
17425        completeSwitchAndInitalize(uss, newUserId, true, false);
17426    }
17427
17428    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17429        completeSwitchAndInitalize(uss, newUserId, false, true);
17430    }
17431
17432    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17433            boolean clearInitializing, boolean clearSwitching) {
17434        boolean unfrozen = false;
17435        synchronized (this) {
17436            if (clearInitializing) {
17437                uss.initializing = false;
17438                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17439            }
17440            if (clearSwitching) {
17441                uss.switching = false;
17442            }
17443            if (!uss.switching && !uss.initializing) {
17444                mWindowManager.stopFreezingScreen();
17445                unfrozen = true;
17446            }
17447        }
17448        if (unfrozen) {
17449            final int N = mUserSwitchObservers.beginBroadcast();
17450            for (int i=0; i<N; i++) {
17451                try {
17452                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17453                } catch (RemoteException e) {
17454                }
17455            }
17456            mUserSwitchObservers.finishBroadcast();
17457        }
17458    }
17459
17460    void scheduleStartProfilesLocked() {
17461        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17462            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17463                    DateUtils.SECOND_IN_MILLIS);
17464        }
17465    }
17466
17467    void startProfilesLocked() {
17468        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17469        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17470                mCurrentUserId, false /* enabledOnly */);
17471        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17472        for (UserInfo user : profiles) {
17473            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17474                    && user.id != mCurrentUserId) {
17475                toStart.add(user);
17476            }
17477        }
17478        final int n = toStart.size();
17479        int i = 0;
17480        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17481            startUserInBackground(toStart.get(i).id);
17482        }
17483        if (i < n) {
17484            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17485        }
17486    }
17487
17488    void finishUserBoot(UserStartedState uss) {
17489        synchronized (this) {
17490            if (uss.mState == UserStartedState.STATE_BOOTING
17491                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17492                uss.mState = UserStartedState.STATE_RUNNING;
17493                final int userId = uss.mHandle.getIdentifier();
17494                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17495                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17496                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17497                broadcastIntentLocked(null, null, intent,
17498                        null, null, 0, null, null,
17499                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17500                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17501            }
17502        }
17503    }
17504
17505    void finishUserSwitch(UserStartedState uss) {
17506        synchronized (this) {
17507            finishUserBoot(uss);
17508
17509            startProfilesLocked();
17510
17511            int num = mUserLru.size();
17512            int i = 0;
17513            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17514                Integer oldUserId = mUserLru.get(i);
17515                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17516                if (oldUss == null) {
17517                    // Shouldn't happen, but be sane if it does.
17518                    mUserLru.remove(i);
17519                    num--;
17520                    continue;
17521                }
17522                if (oldUss.mState == UserStartedState.STATE_STOPPING
17523                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17524                    // This user is already stopping, doesn't count.
17525                    num--;
17526                    i++;
17527                    continue;
17528                }
17529                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17530                    // Owner and current can't be stopped, but count as running.
17531                    i++;
17532                    continue;
17533                }
17534                // This is a user to be stopped.
17535                stopUserLocked(oldUserId, null);
17536                num--;
17537                i++;
17538            }
17539        }
17540    }
17541
17542    @Override
17543    public int stopUser(final int userId, final IStopUserCallback callback) {
17544        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17545                != PackageManager.PERMISSION_GRANTED) {
17546            String msg = "Permission Denial: switchUser() from pid="
17547                    + Binder.getCallingPid()
17548                    + ", uid=" + Binder.getCallingUid()
17549                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17550            Slog.w(TAG, msg);
17551            throw new SecurityException(msg);
17552        }
17553        if (userId <= 0) {
17554            throw new IllegalArgumentException("Can't stop primary user " + userId);
17555        }
17556        synchronized (this) {
17557            return stopUserLocked(userId, callback);
17558        }
17559    }
17560
17561    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17562        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17563        if (mCurrentUserId == userId) {
17564            return ActivityManager.USER_OP_IS_CURRENT;
17565        }
17566
17567        final UserStartedState uss = mStartedUsers.get(userId);
17568        if (uss == null) {
17569            // User is not started, nothing to do...  but we do need to
17570            // callback if requested.
17571            if (callback != null) {
17572                mHandler.post(new Runnable() {
17573                    @Override
17574                    public void run() {
17575                        try {
17576                            callback.userStopped(userId);
17577                        } catch (RemoteException e) {
17578                        }
17579                    }
17580                });
17581            }
17582            return ActivityManager.USER_OP_SUCCESS;
17583        }
17584
17585        if (callback != null) {
17586            uss.mStopCallbacks.add(callback);
17587        }
17588
17589        if (uss.mState != UserStartedState.STATE_STOPPING
17590                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17591            uss.mState = UserStartedState.STATE_STOPPING;
17592            updateStartedUserArrayLocked();
17593
17594            long ident = Binder.clearCallingIdentity();
17595            try {
17596                // We are going to broadcast ACTION_USER_STOPPING and then
17597                // once that is done send a final ACTION_SHUTDOWN and then
17598                // stop the user.
17599                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17600                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17601                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17602                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17603                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17604                // This is the result receiver for the final shutdown broadcast.
17605                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17606                    @Override
17607                    public void performReceive(Intent intent, int resultCode, String data,
17608                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17609                        finishUserStop(uss);
17610                    }
17611                };
17612                // This is the result receiver for the initial stopping broadcast.
17613                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17614                    @Override
17615                    public void performReceive(Intent intent, int resultCode, String data,
17616                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17617                        // On to the next.
17618                        synchronized (ActivityManagerService.this) {
17619                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17620                                // Whoops, we are being started back up.  Abort, abort!
17621                                return;
17622                            }
17623                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17624                        }
17625                        mBatteryStatsService.noteEvent(
17626                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17627                                Integer.toString(userId), userId);
17628                        mSystemServiceManager.stopUser(userId);
17629                        broadcastIntentLocked(null, null, shutdownIntent,
17630                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17631                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17632                    }
17633                };
17634                // Kick things off.
17635                broadcastIntentLocked(null, null, stoppingIntent,
17636                        null, stoppingReceiver, 0, null, null,
17637                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17638                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17639            } finally {
17640                Binder.restoreCallingIdentity(ident);
17641            }
17642        }
17643
17644        return ActivityManager.USER_OP_SUCCESS;
17645    }
17646
17647    void finishUserStop(UserStartedState uss) {
17648        final int userId = uss.mHandle.getIdentifier();
17649        boolean stopped;
17650        ArrayList<IStopUserCallback> callbacks;
17651        synchronized (this) {
17652            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17653            if (mStartedUsers.get(userId) != uss) {
17654                stopped = false;
17655            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17656                stopped = false;
17657            } else {
17658                stopped = true;
17659                // User can no longer run.
17660                mStartedUsers.remove(userId);
17661                mUserLru.remove(Integer.valueOf(userId));
17662                updateStartedUserArrayLocked();
17663
17664                // Clean up all state and processes associated with the user.
17665                // Kill all the processes for the user.
17666                forceStopUserLocked(userId, "finish user");
17667            }
17668        }
17669
17670        // Explicitly remove the old information in mRecentTasks.
17671        removeRecentTasksForUser(userId);
17672
17673        for (int i=0; i<callbacks.size(); i++) {
17674            try {
17675                if (stopped) callbacks.get(i).userStopped(userId);
17676                else callbacks.get(i).userStopAborted(userId);
17677            } catch (RemoteException e) {
17678            }
17679        }
17680
17681        if (stopped) {
17682            mSystemServiceManager.cleanupUser(userId);
17683            synchronized (this) {
17684                mStackSupervisor.removeUserLocked(userId);
17685            }
17686        }
17687    }
17688
17689    @Override
17690    public UserInfo getCurrentUser() {
17691        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17692                != PackageManager.PERMISSION_GRANTED) && (
17693                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17694                != PackageManager.PERMISSION_GRANTED)) {
17695            String msg = "Permission Denial: getCurrentUser() from pid="
17696                    + Binder.getCallingPid()
17697                    + ", uid=" + Binder.getCallingUid()
17698                    + " requires " + INTERACT_ACROSS_USERS;
17699            Slog.w(TAG, msg);
17700            throw new SecurityException(msg);
17701        }
17702        synchronized (this) {
17703            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17704        }
17705    }
17706
17707    int getCurrentUserIdLocked() {
17708        return mCurrentUserId;
17709    }
17710
17711    @Override
17712    public boolean isUserRunning(int userId, boolean orStopped) {
17713        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17714                != PackageManager.PERMISSION_GRANTED) {
17715            String msg = "Permission Denial: isUserRunning() from pid="
17716                    + Binder.getCallingPid()
17717                    + ", uid=" + Binder.getCallingUid()
17718                    + " requires " + INTERACT_ACROSS_USERS;
17719            Slog.w(TAG, msg);
17720            throw new SecurityException(msg);
17721        }
17722        synchronized (this) {
17723            return isUserRunningLocked(userId, orStopped);
17724        }
17725    }
17726
17727    boolean isUserRunningLocked(int userId, boolean orStopped) {
17728        UserStartedState state = mStartedUsers.get(userId);
17729        if (state == null) {
17730            return false;
17731        }
17732        if (orStopped) {
17733            return true;
17734        }
17735        return state.mState != UserStartedState.STATE_STOPPING
17736                && state.mState != UserStartedState.STATE_SHUTDOWN;
17737    }
17738
17739    @Override
17740    public int[] getRunningUserIds() {
17741        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17742                != PackageManager.PERMISSION_GRANTED) {
17743            String msg = "Permission Denial: isUserRunning() from pid="
17744                    + Binder.getCallingPid()
17745                    + ", uid=" + Binder.getCallingUid()
17746                    + " requires " + INTERACT_ACROSS_USERS;
17747            Slog.w(TAG, msg);
17748            throw new SecurityException(msg);
17749        }
17750        synchronized (this) {
17751            return mStartedUserArray;
17752        }
17753    }
17754
17755    private void updateStartedUserArrayLocked() {
17756        int num = 0;
17757        for (int i=0; i<mStartedUsers.size();  i++) {
17758            UserStartedState uss = mStartedUsers.valueAt(i);
17759            // This list does not include stopping users.
17760            if (uss.mState != UserStartedState.STATE_STOPPING
17761                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17762                num++;
17763            }
17764        }
17765        mStartedUserArray = new int[num];
17766        num = 0;
17767        for (int i=0; i<mStartedUsers.size();  i++) {
17768            UserStartedState uss = mStartedUsers.valueAt(i);
17769            if (uss.mState != UserStartedState.STATE_STOPPING
17770                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17771                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17772                num++;
17773            }
17774        }
17775    }
17776
17777    @Override
17778    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17779        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17780                != PackageManager.PERMISSION_GRANTED) {
17781            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17782                    + Binder.getCallingPid()
17783                    + ", uid=" + Binder.getCallingUid()
17784                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17785            Slog.w(TAG, msg);
17786            throw new SecurityException(msg);
17787        }
17788
17789        mUserSwitchObservers.register(observer);
17790    }
17791
17792    @Override
17793    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17794        mUserSwitchObservers.unregister(observer);
17795    }
17796
17797    private boolean userExists(int userId) {
17798        if (userId == 0) {
17799            return true;
17800        }
17801        UserManagerService ums = getUserManagerLocked();
17802        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17803    }
17804
17805    int[] getUsersLocked() {
17806        UserManagerService ums = getUserManagerLocked();
17807        return ums != null ? ums.getUserIds() : new int[] { 0 };
17808    }
17809
17810    UserManagerService getUserManagerLocked() {
17811        if (mUserManager == null) {
17812            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17813            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17814        }
17815        return mUserManager;
17816    }
17817
17818    private int applyUserId(int uid, int userId) {
17819        return UserHandle.getUid(userId, uid);
17820    }
17821
17822    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17823        if (info == null) return null;
17824        ApplicationInfo newInfo = new ApplicationInfo(info);
17825        newInfo.uid = applyUserId(info.uid, userId);
17826        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17827                + info.packageName;
17828        return newInfo;
17829    }
17830
17831    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17832        if (aInfo == null
17833                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17834            return aInfo;
17835        }
17836
17837        ActivityInfo info = new ActivityInfo(aInfo);
17838        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17839        return info;
17840    }
17841
17842    private final class LocalService extends ActivityManagerInternal {
17843        @Override
17844        public void goingToSleep() {
17845            ActivityManagerService.this.goingToSleep();
17846        }
17847
17848        @Override
17849        public void wakingUp() {
17850            ActivityManagerService.this.wakingUp();
17851        }
17852    }
17853
17854    /**
17855     * An implementation of IAppTask, that allows an app to manage its own tasks via
17856     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17857     * only the process that calls getAppTasks() can call the AppTask methods.
17858     */
17859    class AppTaskImpl extends IAppTask.Stub {
17860        private int mTaskId;
17861        private int mCallingUid;
17862
17863        public AppTaskImpl(int taskId, int callingUid) {
17864            mTaskId = taskId;
17865            mCallingUid = callingUid;
17866        }
17867
17868        @Override
17869        public void finishAndRemoveTask() {
17870            // Ensure that we are called from the same process that created this AppTask
17871            if (mCallingUid != Binder.getCallingUid()) {
17872                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17873                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17874                return;
17875            }
17876
17877            synchronized (ActivityManagerService.this) {
17878                long origId = Binder.clearCallingIdentity();
17879                try {
17880                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17881                    if (tr != null) {
17882                        // Only kill the process if we are not a new document
17883                        int flags = tr.getBaseIntent().getFlags();
17884                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17885                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17886                        removeTaskByIdLocked(mTaskId,
17887                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17888                    }
17889                } finally {
17890                    Binder.restoreCallingIdentity(origId);
17891                }
17892            }
17893        }
17894
17895        @Override
17896        public ActivityManager.RecentTaskInfo getTaskInfo() {
17897            // Ensure that we are called from the same process that created this AppTask
17898            if (mCallingUid != Binder.getCallingUid()) {
17899                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17900                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17901                return null;
17902            }
17903
17904            synchronized (ActivityManagerService.this) {
17905                long origId = Binder.clearCallingIdentity();
17906                try {
17907                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17908                    if (tr != null) {
17909                        return createRecentTaskInfoFromTaskRecord(tr);
17910                    }
17911                } finally {
17912                    Binder.restoreCallingIdentity(origId);
17913                }
17914                return null;
17915            }
17916        }
17917    }
17918}
17919