ActivityManagerService.java revision 465fa3963534e41ead0dce1273b71fd50c58c973
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.os.UserManager;
184import android.provider.Settings;
185import android.text.format.DateUtils;
186import android.text.format.Time;
187import android.util.AtomicFile;
188import android.util.EventLog;
189import android.util.Log;
190import android.util.Pair;
191import android.util.PrintWriterPrinter;
192import android.util.Slog;
193import android.util.SparseArray;
194import android.util.TimeUtils;
195import android.util.Xml;
196import android.view.Gravity;
197import android.view.LayoutInflater;
198import android.view.View;
199import android.view.WindowManager;
200import dalvik.system.VMRuntime;
201
202import java.io.BufferedInputStream;
203import java.io.BufferedOutputStream;
204import java.io.DataInputStream;
205import java.io.DataOutputStream;
206import java.io.File;
207import java.io.FileDescriptor;
208import java.io.FileInputStream;
209import java.io.FileNotFoundException;
210import java.io.FileOutputStream;
211import java.io.IOException;
212import java.io.InputStreamReader;
213import java.io.PrintWriter;
214import java.io.StringWriter;
215import java.lang.ref.WeakReference;
216import java.util.ArrayList;
217import java.util.Arrays;
218import java.util.Collections;
219import java.util.Comparator;
220import java.util.HashMap;
221import java.util.HashSet;
222import java.util.Iterator;
223import java.util.List;
224import java.util.Locale;
225import java.util.Map;
226import java.util.Set;
227import java.util.concurrent.atomic.AtomicBoolean;
228import java.util.concurrent.atomic.AtomicLong;
229
230public final class ActivityManagerService extends ActivityManagerNative
231        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
232
233    private static final String USER_DATA_DIR = "/data/user/";
234    // File that stores last updated system version and called preboot receivers
235    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
236
237    static final String TAG = "ActivityManager";
238    static final String TAG_MU = "ActivityManagerServiceMU";
239    static final boolean DEBUG = false;
240    static final boolean localLOGV = DEBUG;
241    static final boolean DEBUG_BACKUP = localLOGV || false;
242    static final boolean DEBUG_BROADCAST = localLOGV || false;
243    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
244    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
245    static final boolean DEBUG_CLEANUP = localLOGV || false;
246    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
247    static final boolean DEBUG_FOCUS = false;
248    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
249    static final boolean DEBUG_MU = localLOGV || false;
250    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
251    static final boolean DEBUG_LRU = localLOGV || false;
252    static final boolean DEBUG_PAUSE = localLOGV || false;
253    static final boolean DEBUG_POWER = localLOGV || false;
254    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
255    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
256    static final boolean DEBUG_PROCESSES = localLOGV || false;
257    static final boolean DEBUG_PROVIDER = localLOGV || false;
258    static final boolean DEBUG_RESULTS = localLOGV || false;
259    static final boolean DEBUG_SERVICE = localLOGV || false;
260    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
261    static final boolean DEBUG_STACK = localLOGV || false;
262    static final boolean DEBUG_SWITCH = localLOGV || false;
263    static final boolean DEBUG_TASKS = localLOGV || false;
264    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
265    static final boolean DEBUG_TRANSITION = localLOGV || false;
266    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
267    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
268    static final boolean DEBUG_VISBILITY = localLOGV || false;
269    static final boolean DEBUG_PSS = localLOGV || false;
270    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
271    static final boolean DEBUG_RECENTS = localLOGV || false;
272    static final boolean VALIDATE_TOKENS = false;
273    static final boolean SHOW_ACTIVITY_START_TIME = true;
274
275    // Control over CPU and battery monitoring.
276    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
277    static final boolean MONITOR_CPU_USAGE = true;
278    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
279    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
280    static final boolean MONITOR_THREAD_CPU_USAGE = false;
281
282    // The flags that are set for all calls we make to the package manager.
283    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
284
285    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
286
287    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
288
289    // Maximum number recent bitmaps to keep in memory.
290    static final int MAX_RECENT_BITMAPS = 5;
291
292    // Amount of time after a call to stopAppSwitches() during which we will
293    // prevent further untrusted switches from happening.
294    static final long APP_SWITCH_DELAY_TIME = 5*1000;
295
296    // How long we wait for a launched process to attach to the activity manager
297    // before we decide it's never going to come up for real.
298    static final int PROC_START_TIMEOUT = 10*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real, when the process was
302    // started with a wrapper for instrumentation (such as Valgrind) because it
303    // could take much longer than usual.
304    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
305
306    // How long to wait after going idle before forcing apps to GC.
307    static final int GC_TIMEOUT = 5*1000;
308
309    // The minimum amount of time between successive GC requests for a process.
310    static final int GC_MIN_INTERVAL = 60*1000;
311
312    // The minimum amount of time between successive PSS requests for a process.
313    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process
316    // when the request is due to the memory state being lowered.
317    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
318
319    // The rate at which we check for apps using excessive power -- 15 mins.
320    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
321
322    // The minimum sample duration we will allow before deciding we have
323    // enough data on wake locks to start killing things.
324    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on CPU usage to start killing things.
328    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // How long we allow a receiver to run before giving up on it.
331    static final int BROADCAST_FG_TIMEOUT = 10*1000;
332    static final int BROADCAST_BG_TIMEOUT = 60*1000;
333
334    // How long we wait until we timeout on key dispatching.
335    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
336
337    // How long we wait until we timeout on key dispatching during instrumentation.
338    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
339
340    // Amount of time we wait for observers to handle a user switch before
341    // giving up on them and unfreezing the screen.
342    static final int USER_SWITCH_TIMEOUT = 2*1000;
343
344    // Maximum number of users we allow to be running at a time.
345    static final int MAX_RUNNING_USERS = 3;
346
347    // How long to wait in getAssistContextExtras for the activity and foreground services
348    // to respond with the result.
349    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
350
351    // Maximum number of persisted Uri grants a package is allowed
352    static final int MAX_PERSISTED_URI_GRANTS = 128;
353
354    static final int MY_PID = Process.myPid();
355
356    static final String[] EMPTY_STRING_ARRAY = new String[0];
357
358    // How many bytes to write into the dropbox log before truncating
359    static final int DROPBOX_MAX_SIZE = 256 * 1024;
360
361    // Access modes for handleIncomingUser.
362    static final int ALLOW_NON_FULL = 0;
363    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
364    static final int ALLOW_FULL_ONLY = 2;
365
366    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
367
368    /** All system services */
369    SystemServiceManager mSystemServiceManager;
370
371    /** Run all ActivityStacks through this */
372    ActivityStackSupervisor mStackSupervisor;
373
374    public IntentFirewall mIntentFirewall;
375
376    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
377    // default actuion automatically.  Important for devices without direct input
378    // devices.
379    private boolean mShowDialogs = true;
380
381    BroadcastQueue mFgBroadcastQueue;
382    BroadcastQueue mBgBroadcastQueue;
383    // Convenient for easy iteration over the queues. Foreground is first
384    // so that dispatch of foreground broadcasts gets precedence.
385    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
386
387    BroadcastQueue broadcastQueueForIntent(Intent intent) {
388        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
389        if (DEBUG_BACKGROUND_BROADCAST) {
390            Slog.i(TAG, "Broadcast intent " + intent + " on "
391                    + (isFg ? "foreground" : "background")
392                    + " queue");
393        }
394        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
395    }
396
397    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
398        for (BroadcastQueue queue : mBroadcastQueues) {
399            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
400            if (r != null) {
401                return r;
402            }
403        }
404        return null;
405    }
406
407    /**
408     * Activity we have told the window manager to have key focus.
409     */
410    ActivityRecord mFocusedActivity = null;
411
412    /**
413     * List of intents that were used to start the most recent tasks.
414     */
415    ArrayList<TaskRecord> mRecentTasks;
416    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
417
418    /**
419     * For addAppTask: cached of the last activity component that was added.
420     */
421    ComponentName mLastAddedTaskComponent;
422
423    /**
424     * For addAppTask: cached of the last activity uid that was added.
425     */
426    int mLastAddedTaskUid;
427
428    /**
429     * For addAppTask: cached of the last ActivityInfo that was added.
430     */
431    ActivityInfo mLastAddedTaskActivity;
432
433    public class PendingAssistExtras extends Binder implements Runnable {
434        public final ActivityRecord activity;
435        public boolean haveResult = false;
436        public Bundle result = null;
437        public PendingAssistExtras(ActivityRecord _activity) {
438            activity = _activity;
439        }
440        @Override
441        public void run() {
442            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
443            synchronized (this) {
444                haveResult = true;
445                notifyAll();
446            }
447        }
448    }
449
450    final ArrayList<PendingAssistExtras> mPendingAssistExtras
451            = new ArrayList<PendingAssistExtras>();
452
453    /**
454     * Process management.
455     */
456    final ProcessList mProcessList = new ProcessList();
457
458    /**
459     * All of the applications we currently have running organized by name.
460     * The keys are strings of the application package name (as
461     * returned by the package manager), and the keys are ApplicationRecord
462     * objects.
463     */
464    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
465
466    /**
467     * Tracking long-term execution of processes to look for abuse and other
468     * bad app behavior.
469     */
470    final ProcessStatsService mProcessStats;
471
472    /**
473     * The currently running isolated processes.
474     */
475    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
476
477    /**
478     * Counter for assigning isolated process uids, to avoid frequently reusing the
479     * same ones.
480     */
481    int mNextIsolatedProcessUid = 0;
482
483    /**
484     * The currently running heavy-weight process, if any.
485     */
486    ProcessRecord mHeavyWeightProcess = null;
487
488    /**
489     * The last time that various processes have crashed.
490     */
491    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
492
493    /**
494     * Information about a process that is currently marked as bad.
495     */
496    static final class BadProcessInfo {
497        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
498            this.time = time;
499            this.shortMsg = shortMsg;
500            this.longMsg = longMsg;
501            this.stack = stack;
502        }
503
504        final long time;
505        final String shortMsg;
506        final String longMsg;
507        final String stack;
508    }
509
510    /**
511     * Set of applications that we consider to be bad, and will reject
512     * incoming broadcasts from (which the user has no control over).
513     * Processes are added to this set when they have crashed twice within
514     * a minimum amount of time; they are removed from it when they are
515     * later restarted (hopefully due to some user action).  The value is the
516     * time it was added to the list.
517     */
518    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
519
520    /**
521     * All of the processes we currently have running organized by pid.
522     * The keys are the pid running the application.
523     *
524     * <p>NOTE: This object is protected by its own lock, NOT the global
525     * activity manager lock!
526     */
527    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
528
529    /**
530     * All of the processes that have been forced to be foreground.  The key
531     * is the pid of the caller who requested it (we hold a death
532     * link on it).
533     */
534    abstract class ForegroundToken implements IBinder.DeathRecipient {
535        int pid;
536        IBinder token;
537    }
538    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
539
540    /**
541     * List of records for processes that someone had tried to start before the
542     * system was ready.  We don't start them at that point, but ensure they
543     * are started by the time booting is complete.
544     */
545    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
546
547    /**
548     * List of persistent applications that are in the process
549     * of being started.
550     */
551    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Processes that are being forcibly torn down.
555     */
556    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of running applications, sorted by recent usage.
560     * The first entry in the list is the least recently used.
561     */
562    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Where in mLruProcesses that the processes hosting activities start.
566     */
567    int mLruProcessActivityStart = 0;
568
569    /**
570     * Where in mLruProcesses that the processes hosting services start.
571     * This is after (lower index) than mLruProcessesActivityStart.
572     */
573    int mLruProcessServiceStart = 0;
574
575    /**
576     * List of processes that should gc as soon as things are idle.
577     */
578    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
579
580    /**
581     * Processes we want to collect PSS data from.
582     */
583    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
584
585    /**
586     * Last time we requested PSS data of all processes.
587     */
588    long mLastFullPssTime = SystemClock.uptimeMillis();
589
590    /**
591     * If set, the next time we collect PSS data we should do a full collection
592     * with data from native processes and the kernel.
593     */
594    boolean mFullPssPending = false;
595
596    /**
597     * This is the process holding what we currently consider to be
598     * the "home" activity.
599     */
600    ProcessRecord mHomeProcess;
601
602    /**
603     * This is the process holding the activity the user last visited that
604     * is in a different process from the one they are currently in.
605     */
606    ProcessRecord mPreviousProcess;
607
608    /**
609     * The time at which the previous process was last visible.
610     */
611    long mPreviousProcessVisibleTime;
612
613    /**
614     * Which uses have been started, so are allowed to run code.
615     */
616    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
617
618    /**
619     * LRU list of history of current users.  Most recently current is at the end.
620     */
621    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
622
623    /**
624     * Constant array of the users that are currently started.
625     */
626    int[] mStartedUserArray = new int[] { 0 };
627
628    /**
629     * Registered observers of the user switching mechanics.
630     */
631    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
632            = new RemoteCallbackList<IUserSwitchObserver>();
633
634    /**
635     * Currently active user switch.
636     */
637    Object mCurUserSwitchCallback;
638
639    /**
640     * Packages that the user has asked to have run in screen size
641     * compatibility mode instead of filling the screen.
642     */
643    final CompatModePackages mCompatModePackages;
644
645    /**
646     * Set of IntentSenderRecord objects that are currently active.
647     */
648    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
649            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
650
651    /**
652     * Fingerprints (hashCode()) of stack traces that we've
653     * already logged DropBox entries for.  Guarded by itself.  If
654     * something (rogue user app) forces this over
655     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
656     */
657    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
658    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
659
660    /**
661     * Strict Mode background batched logging state.
662     *
663     * The string buffer is guarded by itself, and its lock is also
664     * used to determine if another batched write is already
665     * in-flight.
666     */
667    private final StringBuilder mStrictModeBuffer = new StringBuilder();
668
669    /**
670     * Keeps track of all IIntentReceivers that have been registered for
671     * broadcasts.  Hash keys are the receiver IBinder, hash value is
672     * a ReceiverList.
673     */
674    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
675            new HashMap<IBinder, ReceiverList>();
676
677    /**
678     * Resolver for broadcast intents to registered receivers.
679     * Holds BroadcastFilter (subclass of IntentFilter).
680     */
681    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
682            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
683        @Override
684        protected boolean allowFilterResult(
685                BroadcastFilter filter, List<BroadcastFilter> dest) {
686            IBinder target = filter.receiverList.receiver.asBinder();
687            for (int i=dest.size()-1; i>=0; i--) {
688                if (dest.get(i).receiverList.receiver.asBinder() == target) {
689                    return false;
690                }
691            }
692            return true;
693        }
694
695        @Override
696        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
697            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
698                    || userId == filter.owningUserId) {
699                return super.newResult(filter, match, userId);
700            }
701            return null;
702        }
703
704        @Override
705        protected BroadcastFilter[] newArray(int size) {
706            return new BroadcastFilter[size];
707        }
708
709        @Override
710        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
711            return packageName.equals(filter.packageName);
712        }
713    };
714
715    /**
716     * State of all active sticky broadcasts per user.  Keys are the action of the
717     * sticky Intent, values are an ArrayList of all broadcasted intents with
718     * that action (which should usually be one).  The SparseArray is keyed
719     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
720     * for stickies that are sent to all users.
721     */
722    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
723            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
724
725    final ActiveServices mServices;
726
727    /**
728     * Backup/restore process management
729     */
730    String mBackupAppName = null;
731    BackupRecord mBackupTarget = null;
732
733    final ProviderMap mProviderMap;
734
735    /**
736     * List of content providers who have clients waiting for them.  The
737     * application is currently being launched and the provider will be
738     * removed from this list once it is published.
739     */
740    final ArrayList<ContentProviderRecord> mLaunchingProviders
741            = new ArrayList<ContentProviderRecord>();
742
743    /**
744     * File storing persisted {@link #mGrantedUriPermissions}.
745     */
746    private final AtomicFile mGrantFile;
747
748    /** XML constants used in {@link #mGrantFile} */
749    private static final String TAG_URI_GRANTS = "uri-grants";
750    private static final String TAG_URI_GRANT = "uri-grant";
751    private static final String ATTR_USER_HANDLE = "userHandle";
752    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
753    private static final String ATTR_TARGET_USER_ID = "targetUserId";
754    private static final String ATTR_SOURCE_PKG = "sourcePkg";
755    private static final String ATTR_TARGET_PKG = "targetPkg";
756    private static final String ATTR_URI = "uri";
757    private static final String ATTR_MODE_FLAGS = "modeFlags";
758    private static final String ATTR_CREATED_TIME = "createdTime";
759    private static final String ATTR_PREFIX = "prefix";
760
761    /**
762     * Global set of specific {@link Uri} permissions that have been granted.
763     * This optimized lookup structure maps from {@link UriPermission#targetUid}
764     * to {@link UriPermission#uri} to {@link UriPermission}.
765     */
766    @GuardedBy("this")
767    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
768            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
769
770    public static class GrantUri {
771        public final int sourceUserId;
772        public final Uri uri;
773        public boolean prefix;
774
775        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
776            this.sourceUserId = sourceUserId;
777            this.uri = uri;
778            this.prefix = prefix;
779        }
780
781        @Override
782        public int hashCode() {
783            return toString().hashCode();
784        }
785
786        @Override
787        public boolean equals(Object o) {
788            if (o instanceof GrantUri) {
789                GrantUri other = (GrantUri) o;
790                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
791                        && prefix == other.prefix;
792            }
793            return false;
794        }
795
796        @Override
797        public String toString() {
798            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
799            if (prefix) result += " [prefix]";
800            return result;
801        }
802
803        public String toSafeString() {
804            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
805            if (prefix) result += " [prefix]";
806            return result;
807        }
808
809        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
810            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
811                    ContentProvider.getUriWithoutUserId(uri), false);
812        }
813    }
814
815    CoreSettingsObserver mCoreSettingsObserver;
816
817    /**
818     * Thread-local storage used to carry caller permissions over through
819     * indirect content-provider access.
820     */
821    private class Identity {
822        public int pid;
823        public int uid;
824
825        Identity(int _pid, int _uid) {
826            pid = _pid;
827            uid = _uid;
828        }
829    }
830
831    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
832
833    /**
834     * All information we have collected about the runtime performance of
835     * any user id that can impact battery performance.
836     */
837    final BatteryStatsService mBatteryStatsService;
838
839    /**
840     * Information about component usage
841     */
842    UsageStatsManagerInternal mUsageStatsService;
843
844    /**
845     * Information about and control over application operations
846     */
847    final AppOpsService mAppOpsService;
848
849    /**
850     * Save recent tasks information across reboots.
851     */
852    final TaskPersister mTaskPersister;
853
854    /**
855     * Current configuration information.  HistoryRecord objects are given
856     * a reference to this object to indicate which configuration they are
857     * currently running in, so this object must be kept immutable.
858     */
859    Configuration mConfiguration = new Configuration();
860
861    /**
862     * Current sequencing integer of the configuration, for skipping old
863     * configurations.
864     */
865    int mConfigurationSeq = 0;
866
867    /**
868     * Hardware-reported OpenGLES version.
869     */
870    final int GL_ES_VERSION;
871
872    /**
873     * List of initialization arguments to pass to all processes when binding applications to them.
874     * For example, references to the commonly used services.
875     */
876    HashMap<String, IBinder> mAppBindArgs;
877
878    /**
879     * Temporary to avoid allocations.  Protected by main lock.
880     */
881    final StringBuilder mStringBuilder = new StringBuilder(256);
882
883    /**
884     * Used to control how we initialize the service.
885     */
886    ComponentName mTopComponent;
887    String mTopAction = Intent.ACTION_MAIN;
888    String mTopData;
889    boolean mProcessesReady = false;
890    boolean mSystemReady = false;
891    boolean mBooting = false;
892    boolean mCallFinishBooting = false;
893    boolean mBootAnimationComplete = false;
894    boolean mWaitingUpdate = false;
895    boolean mDidUpdate = false;
896    boolean mOnBattery = false;
897    boolean mLaunchWarningShown = false;
898
899    Context mContext;
900
901    int mFactoryTest;
902
903    boolean mCheckedForSetup;
904
905    /**
906     * The time at which we will allow normal application switches again,
907     * after a call to {@link #stopAppSwitches()}.
908     */
909    long mAppSwitchesAllowedTime;
910
911    /**
912     * This is set to true after the first switch after mAppSwitchesAllowedTime
913     * is set; any switches after that will clear the time.
914     */
915    boolean mDidAppSwitch;
916
917    /**
918     * Last time (in realtime) at which we checked for power usage.
919     */
920    long mLastPowerCheckRealtime;
921
922    /**
923     * Last time (in uptime) at which we checked for power usage.
924     */
925    long mLastPowerCheckUptime;
926
927    /**
928     * Set while we are wanting to sleep, to prevent any
929     * activities from being started/resumed.
930     */
931    private boolean mSleeping = false;
932
933    /**
934     * Set while we are running a voice interaction.  This overrides
935     * sleeping while it is active.
936     */
937    private boolean mRunningVoice = false;
938
939    /**
940     * State of external calls telling us if the device is asleep.
941     */
942    private boolean mWentToSleep = false;
943
944    /**
945     * State of external call telling us if the lock screen is shown.
946     */
947    private boolean mLockScreenShown = false;
948
949    /**
950     * Set if we are shutting down the system, similar to sleeping.
951     */
952    boolean mShuttingDown = false;
953
954    /**
955     * Current sequence id for oom_adj computation traversal.
956     */
957    int mAdjSeq = 0;
958
959    /**
960     * Current sequence id for process LRU updating.
961     */
962    int mLruSeq = 0;
963
964    /**
965     * Keep track of the non-cached/empty process we last found, to help
966     * determine how to distribute cached/empty processes next time.
967     */
968    int mNumNonCachedProcs = 0;
969
970    /**
971     * Keep track of the number of cached hidden procs, to balance oom adj
972     * distribution between those and empty procs.
973     */
974    int mNumCachedHiddenProcs = 0;
975
976    /**
977     * Keep track of the number of service processes we last found, to
978     * determine on the next iteration which should be B services.
979     */
980    int mNumServiceProcs = 0;
981    int mNewNumAServiceProcs = 0;
982    int mNewNumServiceProcs = 0;
983
984    /**
985     * Allow the current computed overall memory level of the system to go down?
986     * This is set to false when we are killing processes for reasons other than
987     * memory management, so that the now smaller process list will not be taken as
988     * an indication that memory is tighter.
989     */
990    boolean mAllowLowerMemLevel = false;
991
992    /**
993     * The last computed memory level, for holding when we are in a state that
994     * processes are going away for other reasons.
995     */
996    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
997
998    /**
999     * The last total number of process we have, to determine if changes actually look
1000     * like a shrinking number of process due to lower RAM.
1001     */
1002    int mLastNumProcesses;
1003
1004    /**
1005     * The uptime of the last time we performed idle maintenance.
1006     */
1007    long mLastIdleTime = SystemClock.uptimeMillis();
1008
1009    /**
1010     * Total time spent with RAM that has been added in the past since the last idle time.
1011     */
1012    long mLowRamTimeSinceLastIdle = 0;
1013
1014    /**
1015     * If RAM is currently low, when that horrible situation started.
1016     */
1017    long mLowRamStartTime = 0;
1018
1019    /**
1020     * For reporting to battery stats the current top application.
1021     */
1022    private String mCurResumedPackage = null;
1023    private int mCurResumedUid = -1;
1024
1025    /**
1026     * For reporting to battery stats the apps currently running foreground
1027     * service.  The ProcessMap is package/uid tuples; each of these contain
1028     * an array of the currently foreground processes.
1029     */
1030    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1031            = new ProcessMap<ArrayList<ProcessRecord>>();
1032
1033    /**
1034     * This is set if we had to do a delayed dexopt of an app before launching
1035     * it, to increase the ANR timeouts in that case.
1036     */
1037    boolean mDidDexOpt;
1038
1039    /**
1040     * Set if the systemServer made a call to enterSafeMode.
1041     */
1042    boolean mSafeMode;
1043
1044    String mDebugApp = null;
1045    boolean mWaitForDebugger = false;
1046    boolean mDebugTransient = false;
1047    String mOrigDebugApp = null;
1048    boolean mOrigWaitForDebugger = false;
1049    boolean mAlwaysFinishActivities = false;
1050    IActivityController mController = null;
1051    String mProfileApp = null;
1052    ProcessRecord mProfileProc = null;
1053    String mProfileFile;
1054    ParcelFileDescriptor mProfileFd;
1055    int mSamplingInterval = 0;
1056    boolean mAutoStopProfiler = false;
1057    int mProfileType = 0;
1058    String mOpenGlTraceApp = null;
1059
1060    static class ProcessChangeItem {
1061        static final int CHANGE_ACTIVITIES = 1<<0;
1062        static final int CHANGE_PROCESS_STATE = 1<<1;
1063        int changes;
1064        int uid;
1065        int pid;
1066        int processState;
1067        boolean foregroundActivities;
1068    }
1069
1070    final RemoteCallbackList<IProcessObserver> mProcessObservers
1071            = new RemoteCallbackList<IProcessObserver>();
1072    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1073
1074    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1075            = new ArrayList<ProcessChangeItem>();
1076    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1077            = new ArrayList<ProcessChangeItem>();
1078
1079    /**
1080     * Runtime CPU use collection thread.  This object's lock is used to
1081     * perform synchronization with the thread (notifying it to run).
1082     */
1083    final Thread mProcessCpuThread;
1084
1085    /**
1086     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1087     * Must acquire this object's lock when accessing it.
1088     * NOTE: this lock will be held while doing long operations (trawling
1089     * through all processes in /proc), so it should never be acquired by
1090     * any critical paths such as when holding the main activity manager lock.
1091     */
1092    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1093            MONITOR_THREAD_CPU_USAGE);
1094    final AtomicLong mLastCpuTime = new AtomicLong(0);
1095    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1096
1097    long mLastWriteTime = 0;
1098
1099    /**
1100     * Used to retain an update lock when the foreground activity is in
1101     * immersive mode.
1102     */
1103    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1104
1105    /**
1106     * Set to true after the system has finished booting.
1107     */
1108    boolean mBooted = false;
1109
1110    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1111    int mProcessLimitOverride = -1;
1112
1113    WindowManagerService mWindowManager;
1114
1115    final ActivityThread mSystemThread;
1116
1117    // Holds the current foreground user's id
1118    int mCurrentUserId = 0;
1119    // Holds the target user's id during a user switch
1120    int mTargetUserId = UserHandle.USER_NULL;
1121    // If there are multiple profiles for the current user, their ids are here
1122    // Currently only the primary user can have managed profiles
1123    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1124
1125    /**
1126     * Mapping from each known user ID to the profile group ID it is associated with.
1127     */
1128    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1129
1130    private UserManagerService mUserManager;
1131
1132    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1133        final ProcessRecord mApp;
1134        final int mPid;
1135        final IApplicationThread mAppThread;
1136
1137        AppDeathRecipient(ProcessRecord app, int pid,
1138                IApplicationThread thread) {
1139            if (localLOGV) Slog.v(
1140                TAG, "New death recipient " + this
1141                + " for thread " + thread.asBinder());
1142            mApp = app;
1143            mPid = pid;
1144            mAppThread = thread;
1145        }
1146
1147        @Override
1148        public void binderDied() {
1149            if (localLOGV) Slog.v(
1150                TAG, "Death received in " + this
1151                + " for thread " + mAppThread.asBinder());
1152            synchronized(ActivityManagerService.this) {
1153                appDiedLocked(mApp, mPid, mAppThread);
1154            }
1155        }
1156    }
1157
1158    static final int SHOW_ERROR_MSG = 1;
1159    static final int SHOW_NOT_RESPONDING_MSG = 2;
1160    static final int SHOW_FACTORY_ERROR_MSG = 3;
1161    static final int UPDATE_CONFIGURATION_MSG = 4;
1162    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1163    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1164    static final int SERVICE_TIMEOUT_MSG = 12;
1165    static final int UPDATE_TIME_ZONE = 13;
1166    static final int SHOW_UID_ERROR_MSG = 14;
1167    static final int IM_FEELING_LUCKY_MSG = 15;
1168    static final int PROC_START_TIMEOUT_MSG = 20;
1169    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1170    static final int KILL_APPLICATION_MSG = 22;
1171    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1172    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1173    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1174    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1175    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1176    static final int CLEAR_DNS_CACHE_MSG = 28;
1177    static final int UPDATE_HTTP_PROXY_MSG = 29;
1178    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1179    static final int DISPATCH_PROCESSES_CHANGED = 31;
1180    static final int DISPATCH_PROCESS_DIED = 32;
1181    static final int REPORT_MEM_USAGE_MSG = 33;
1182    static final int REPORT_USER_SWITCH_MSG = 34;
1183    static final int CONTINUE_USER_SWITCH_MSG = 35;
1184    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1185    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1186    static final int PERSIST_URI_GRANTS_MSG = 38;
1187    static final int REQUEST_ALL_PSS_MSG = 39;
1188    static final int START_PROFILES_MSG = 40;
1189    static final int UPDATE_TIME = 41;
1190    static final int SYSTEM_USER_START_MSG = 42;
1191    static final int SYSTEM_USER_CURRENT_MSG = 43;
1192    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1193    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1194    static final int START_USER_SWITCH_MSG = 46;
1195
1196    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1197    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1198    static final int FIRST_COMPAT_MODE_MSG = 300;
1199    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1200
1201    AlertDialog mUidAlert;
1202    CompatModeDialog mCompatModeDialog;
1203    long mLastMemUsageReportTime = 0;
1204
1205    private LockToAppRequestDialog mLockToAppRequest;
1206
1207    /**
1208     * Flag whether the current user is a "monkey", i.e. whether
1209     * the UI is driven by a UI automation tool.
1210     */
1211    private boolean mUserIsMonkey;
1212
1213    /** Flag whether the device has a Recents UI */
1214    boolean mHasRecents;
1215
1216    /** The dimensions of the thumbnails in the Recents UI. */
1217    int mThumbnailWidth;
1218    int mThumbnailHeight;
1219
1220    final ServiceThread mHandlerThread;
1221    final MainHandler mHandler;
1222
1223    final class MainHandler extends Handler {
1224        public MainHandler(Looper looper) {
1225            super(looper, null, true);
1226        }
1227
1228        @Override
1229        public void handleMessage(Message msg) {
1230            switch (msg.what) {
1231            case SHOW_ERROR_MSG: {
1232                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1233                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1234                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1235                synchronized (ActivityManagerService.this) {
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    AppErrorResult res = (AppErrorResult) data.get("result");
1238                    if (proc != null && proc.crashDialog != null) {
1239                        Slog.e(TAG, "App already has crash dialog: " + proc);
1240                        if (res != null) {
1241                            res.set(0);
1242                        }
1243                        return;
1244                    }
1245                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1246                            >= Process.FIRST_APPLICATION_UID
1247                            && proc.pid != MY_PID);
1248                    for (int userId : mCurrentProfileIds) {
1249                        isBackground &= (proc.userId != userId);
1250                    }
1251                    if (isBackground && !showBackground) {
1252                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1253                        if (res != null) {
1254                            res.set(0);
1255                        }
1256                        return;
1257                    }
1258                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1259                        Dialog d = new AppErrorDialog(mContext,
1260                                ActivityManagerService.this, res, proc);
1261                        d.show();
1262                        proc.crashDialog = d;
1263                    } else {
1264                        // The device is asleep, so just pretend that the user
1265                        // saw a crash dialog and hit "force quit".
1266                        if (res != null) {
1267                            res.set(0);
1268                        }
1269                    }
1270                }
1271
1272                ensureBootCompleted();
1273            } break;
1274            case SHOW_NOT_RESPONDING_MSG: {
1275                synchronized (ActivityManagerService.this) {
1276                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1277                    ProcessRecord proc = (ProcessRecord)data.get("app");
1278                    if (proc != null && proc.anrDialog != null) {
1279                        Slog.e(TAG, "App already has anr dialog: " + proc);
1280                        return;
1281                    }
1282
1283                    Intent intent = new Intent("android.intent.action.ANR");
1284                    if (!mProcessesReady) {
1285                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1286                                | Intent.FLAG_RECEIVER_FOREGROUND);
1287                    }
1288                    broadcastIntentLocked(null, null, intent,
1289                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1290                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1291
1292                    if (mShowDialogs) {
1293                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1294                                mContext, proc, (ActivityRecord)data.get("activity"),
1295                                msg.arg1 != 0);
1296                        d.show();
1297                        proc.anrDialog = d;
1298                    } else {
1299                        // Just kill the app if there is no dialog to be shown.
1300                        killAppAtUsersRequest(proc, null);
1301                    }
1302                }
1303
1304                ensureBootCompleted();
1305            } break;
1306            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1307                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1308                synchronized (ActivityManagerService.this) {
1309                    ProcessRecord proc = (ProcessRecord) data.get("app");
1310                    if (proc == null) {
1311                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1312                        break;
1313                    }
1314                    if (proc.crashDialog != null) {
1315                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1316                        return;
1317                    }
1318                    AppErrorResult res = (AppErrorResult) data.get("result");
1319                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1320                        Dialog d = new StrictModeViolationDialog(mContext,
1321                                ActivityManagerService.this, res, proc);
1322                        d.show();
1323                        proc.crashDialog = d;
1324                    } else {
1325                        // The device is asleep, so just pretend that the user
1326                        // saw a crash dialog and hit "force quit".
1327                        res.set(0);
1328                    }
1329                }
1330                ensureBootCompleted();
1331            } break;
1332            case SHOW_FACTORY_ERROR_MSG: {
1333                Dialog d = new FactoryErrorDialog(
1334                    mContext, msg.getData().getCharSequence("msg"));
1335                d.show();
1336                ensureBootCompleted();
1337            } break;
1338            case UPDATE_CONFIGURATION_MSG: {
1339                final ContentResolver resolver = mContext.getContentResolver();
1340                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1341            } break;
1342            case GC_BACKGROUND_PROCESSES_MSG: {
1343                synchronized (ActivityManagerService.this) {
1344                    performAppGcsIfAppropriateLocked();
1345                }
1346            } break;
1347            case WAIT_FOR_DEBUGGER_MSG: {
1348                synchronized (ActivityManagerService.this) {
1349                    ProcessRecord app = (ProcessRecord)msg.obj;
1350                    if (msg.arg1 != 0) {
1351                        if (!app.waitedForDebugger) {
1352                            Dialog d = new AppWaitingForDebuggerDialog(
1353                                    ActivityManagerService.this,
1354                                    mContext, app);
1355                            app.waitDialog = d;
1356                            app.waitedForDebugger = true;
1357                            d.show();
1358                        }
1359                    } else {
1360                        if (app.waitDialog != null) {
1361                            app.waitDialog.dismiss();
1362                            app.waitDialog = null;
1363                        }
1364                    }
1365                }
1366            } break;
1367            case SERVICE_TIMEOUT_MSG: {
1368                if (mDidDexOpt) {
1369                    mDidDexOpt = false;
1370                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1371                    nmsg.obj = msg.obj;
1372                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1373                    return;
1374                }
1375                mServices.serviceTimeout((ProcessRecord)msg.obj);
1376            } break;
1377            case UPDATE_TIME_ZONE: {
1378                synchronized (ActivityManagerService.this) {
1379                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1380                        ProcessRecord r = mLruProcesses.get(i);
1381                        if (r.thread != null) {
1382                            try {
1383                                r.thread.updateTimeZone();
1384                            } catch (RemoteException ex) {
1385                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case CLEAR_DNS_CACHE_MSG: {
1392                synchronized (ActivityManagerService.this) {
1393                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1394                        ProcessRecord r = mLruProcesses.get(i);
1395                        if (r.thread != null) {
1396                            try {
1397                                r.thread.clearDnsCache();
1398                            } catch (RemoteException ex) {
1399                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1400                            }
1401                        }
1402                    }
1403                }
1404            } break;
1405            case UPDATE_HTTP_PROXY_MSG: {
1406                ProxyInfo proxy = (ProxyInfo)msg.obj;
1407                String host = "";
1408                String port = "";
1409                String exclList = "";
1410                Uri pacFileUrl = Uri.EMPTY;
1411                if (proxy != null) {
1412                    host = proxy.getHost();
1413                    port = Integer.toString(proxy.getPort());
1414                    exclList = proxy.getExclusionListAsString();
1415                    pacFileUrl = proxy.getPacFileUrl();
1416                }
1417                synchronized (ActivityManagerService.this) {
1418                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1419                        ProcessRecord r = mLruProcesses.get(i);
1420                        if (r.thread != null) {
1421                            try {
1422                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1423                            } catch (RemoteException ex) {
1424                                Slog.w(TAG, "Failed to update http proxy for: " +
1425                                        r.info.processName);
1426                            }
1427                        }
1428                    }
1429                }
1430            } break;
1431            case SHOW_UID_ERROR_MSG: {
1432                String title = "System UIDs Inconsistent";
1433                String text = "UIDs on the system are inconsistent, you need to wipe your"
1434                        + " data partition or your device will be unstable.";
1435                Log.e(TAG, title + ": " + text);
1436                if (mShowDialogs) {
1437                    // XXX This is a temporary dialog, no need to localize.
1438                    AlertDialog d = new BaseErrorDialog(mContext);
1439                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1440                    d.setCancelable(false);
1441                    d.setTitle(title);
1442                    d.setMessage(text);
1443                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1444                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1445                    mUidAlert = d;
1446                    d.show();
1447                }
1448            } break;
1449            case IM_FEELING_LUCKY_MSG: {
1450                if (mUidAlert != null) {
1451                    mUidAlert.dismiss();
1452                    mUidAlert = null;
1453                }
1454            } break;
1455            case PROC_START_TIMEOUT_MSG: {
1456                if (mDidDexOpt) {
1457                    mDidDexOpt = false;
1458                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1459                    nmsg.obj = msg.obj;
1460                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1461                    return;
1462                }
1463                ProcessRecord app = (ProcessRecord)msg.obj;
1464                synchronized (ActivityManagerService.this) {
1465                    processStartTimedOutLocked(app);
1466                }
1467            } break;
1468            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1469                synchronized (ActivityManagerService.this) {
1470                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1471                }
1472            } break;
1473            case KILL_APPLICATION_MSG: {
1474                synchronized (ActivityManagerService.this) {
1475                    int appid = msg.arg1;
1476                    boolean restart = (msg.arg2 == 1);
1477                    Bundle bundle = (Bundle)msg.obj;
1478                    String pkg = bundle.getString("pkg");
1479                    String reason = bundle.getString("reason");
1480                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1481                            false, UserHandle.USER_ALL, reason);
1482                }
1483            } break;
1484            case FINALIZE_PENDING_INTENT_MSG: {
1485                ((PendingIntentRecord)msg.obj).completeFinalize();
1486            } break;
1487            case POST_HEAVY_NOTIFICATION_MSG: {
1488                INotificationManager inm = NotificationManager.getService();
1489                if (inm == null) {
1490                    return;
1491                }
1492
1493                ActivityRecord root = (ActivityRecord)msg.obj;
1494                ProcessRecord process = root.app;
1495                if (process == null) {
1496                    return;
1497                }
1498
1499                try {
1500                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1501                    String text = mContext.getString(R.string.heavy_weight_notification,
1502                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1503                    Notification notification = new Notification();
1504                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1505                    notification.when = 0;
1506                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1507                    notification.tickerText = text;
1508                    notification.defaults = 0; // please be quiet
1509                    notification.sound = null;
1510                    notification.vibrate = null;
1511                    notification.color = mContext.getResources().getColor(
1512                            com.android.internal.R.color.system_notification_accent_color);
1513                    notification.setLatestEventInfo(context, text,
1514                            mContext.getText(R.string.heavy_weight_notification_detail),
1515                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1516                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1517                                    new UserHandle(root.userId)));
1518
1519                    try {
1520                        int[] outId = new int[1];
1521                        inm.enqueueNotificationWithTag("android", "android", null,
1522                                R.string.heavy_weight_notification,
1523                                notification, outId, root.userId);
1524                    } catch (RuntimeException e) {
1525                        Slog.w(ActivityManagerService.TAG,
1526                                "Error showing notification for heavy-weight app", e);
1527                    } catch (RemoteException e) {
1528                    }
1529                } catch (NameNotFoundException e) {
1530                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1531                }
1532            } break;
1533            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1534                INotificationManager inm = NotificationManager.getService();
1535                if (inm == null) {
1536                    return;
1537                }
1538                try {
1539                    inm.cancelNotificationWithTag("android", null,
1540                            R.string.heavy_weight_notification,  msg.arg1);
1541                } catch (RuntimeException e) {
1542                    Slog.w(ActivityManagerService.TAG,
1543                            "Error canceling notification for service", e);
1544                } catch (RemoteException e) {
1545                }
1546            } break;
1547            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1548                synchronized (ActivityManagerService.this) {
1549                    checkExcessivePowerUsageLocked(true);
1550                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1551                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1552                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1553                }
1554            } break;
1555            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1556                synchronized (ActivityManagerService.this) {
1557                    ActivityRecord ar = (ActivityRecord)msg.obj;
1558                    if (mCompatModeDialog != null) {
1559                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1560                                ar.info.applicationInfo.packageName)) {
1561                            return;
1562                        }
1563                        mCompatModeDialog.dismiss();
1564                        mCompatModeDialog = null;
1565                    }
1566                    if (ar != null && false) {
1567                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1568                                ar.packageName)) {
1569                            int mode = mCompatModePackages.computeCompatModeLocked(
1570                                    ar.info.applicationInfo);
1571                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1572                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1573                                mCompatModeDialog = new CompatModeDialog(
1574                                        ActivityManagerService.this, mContext,
1575                                        ar.info.applicationInfo);
1576                                mCompatModeDialog.show();
1577                            }
1578                        }
1579                    }
1580                }
1581                break;
1582            }
1583            case DISPATCH_PROCESSES_CHANGED: {
1584                dispatchProcessesChanged();
1585                break;
1586            }
1587            case DISPATCH_PROCESS_DIED: {
1588                final int pid = msg.arg1;
1589                final int uid = msg.arg2;
1590                dispatchProcessDied(pid, uid);
1591                break;
1592            }
1593            case REPORT_MEM_USAGE_MSG: {
1594                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1595                Thread thread = new Thread() {
1596                    @Override public void run() {
1597                        final SparseArray<ProcessMemInfo> infoMap
1598                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1599                        for (int i=0, N=memInfos.size(); i<N; i++) {
1600                            ProcessMemInfo mi = memInfos.get(i);
1601                            infoMap.put(mi.pid, mi);
1602                        }
1603                        updateCpuStatsNow();
1604                        synchronized (mProcessCpuTracker) {
1605                            final int N = mProcessCpuTracker.countStats();
1606                            for (int i=0; i<N; i++) {
1607                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1608                                if (st.vsize > 0) {
1609                                    long pss = Debug.getPss(st.pid, null);
1610                                    if (pss > 0) {
1611                                        if (infoMap.indexOfKey(st.pid) < 0) {
1612                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1613                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1614                                            mi.pss = pss;
1615                                            memInfos.add(mi);
1616                                        }
1617                                    }
1618                                }
1619                            }
1620                        }
1621
1622                        long totalPss = 0;
1623                        for (int i=0, N=memInfos.size(); i<N; i++) {
1624                            ProcessMemInfo mi = memInfos.get(i);
1625                            if (mi.pss == 0) {
1626                                mi.pss = Debug.getPss(mi.pid, null);
1627                            }
1628                            totalPss += mi.pss;
1629                        }
1630                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1631                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1632                                if (lhs.oomAdj != rhs.oomAdj) {
1633                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1634                                }
1635                                if (lhs.pss != rhs.pss) {
1636                                    return lhs.pss < rhs.pss ? 1 : -1;
1637                                }
1638                                return 0;
1639                            }
1640                        });
1641
1642                        StringBuilder tag = new StringBuilder(128);
1643                        StringBuilder stack = new StringBuilder(128);
1644                        tag.append("Low on memory -- ");
1645                        appendMemBucket(tag, totalPss, "total", false);
1646                        appendMemBucket(stack, totalPss, "total", true);
1647
1648                        StringBuilder logBuilder = new StringBuilder(1024);
1649                        logBuilder.append("Low on memory:\n");
1650
1651                        boolean firstLine = true;
1652                        int lastOomAdj = Integer.MIN_VALUE;
1653                        for (int i=0, N=memInfos.size(); i<N; i++) {
1654                            ProcessMemInfo mi = memInfos.get(i);
1655
1656                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1657                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1658                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1659                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1660                                if (lastOomAdj != mi.oomAdj) {
1661                                    lastOomAdj = mi.oomAdj;
1662                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1663                                        tag.append(" / ");
1664                                    }
1665                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1666                                        if (firstLine) {
1667                                            stack.append(":");
1668                                            firstLine = false;
1669                                        }
1670                                        stack.append("\n\t at ");
1671                                    } else {
1672                                        stack.append("$");
1673                                    }
1674                                } else {
1675                                    tag.append(" ");
1676                                    stack.append("$");
1677                                }
1678                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1679                                    appendMemBucket(tag, mi.pss, mi.name, false);
1680                                }
1681                                appendMemBucket(stack, mi.pss, mi.name, true);
1682                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1683                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1684                                    stack.append("(");
1685                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1686                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1687                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1688                                            stack.append(":");
1689                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1690                                        }
1691                                    }
1692                                    stack.append(")");
1693                                }
1694                            }
1695
1696                            logBuilder.append("  ");
1697                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1698                            logBuilder.append(' ');
1699                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1700                            logBuilder.append(' ');
1701                            ProcessList.appendRamKb(logBuilder, mi.pss);
1702                            logBuilder.append(" kB: ");
1703                            logBuilder.append(mi.name);
1704                            logBuilder.append(" (");
1705                            logBuilder.append(mi.pid);
1706                            logBuilder.append(") ");
1707                            logBuilder.append(mi.adjType);
1708                            logBuilder.append('\n');
1709                            if (mi.adjReason != null) {
1710                                logBuilder.append("                      ");
1711                                logBuilder.append(mi.adjReason);
1712                                logBuilder.append('\n');
1713                            }
1714                        }
1715
1716                        logBuilder.append("           ");
1717                        ProcessList.appendRamKb(logBuilder, totalPss);
1718                        logBuilder.append(" kB: TOTAL\n");
1719
1720                        long[] infos = new long[Debug.MEMINFO_COUNT];
1721                        Debug.getMemInfo(infos);
1722                        logBuilder.append("  MemInfo: ");
1723                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1724                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1725                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1726                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1727                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1728                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1729                            logBuilder.append("  ZRAM: ");
1730                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1731                            logBuilder.append(" kB RAM, ");
1732                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1733                            logBuilder.append(" kB swap total, ");
1734                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1735                            logBuilder.append(" kB swap free\n");
1736                        }
1737                        Slog.i(TAG, logBuilder.toString());
1738
1739                        StringBuilder dropBuilder = new StringBuilder(1024);
1740                        /*
1741                        StringWriter oomSw = new StringWriter();
1742                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1743                        StringWriter catSw = new StringWriter();
1744                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1745                        String[] emptyArgs = new String[] { };
1746                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1747                        oomPw.flush();
1748                        String oomString = oomSw.toString();
1749                        */
1750                        dropBuilder.append(stack);
1751                        dropBuilder.append('\n');
1752                        dropBuilder.append('\n');
1753                        dropBuilder.append(logBuilder);
1754                        dropBuilder.append('\n');
1755                        /*
1756                        dropBuilder.append(oomString);
1757                        dropBuilder.append('\n');
1758                        */
1759                        StringWriter catSw = new StringWriter();
1760                        synchronized (ActivityManagerService.this) {
1761                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1762                            String[] emptyArgs = new String[] { };
1763                            catPw.println();
1764                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1765                            catPw.println();
1766                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1767                                    false, false, null);
1768                            catPw.println();
1769                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1770                            catPw.flush();
1771                        }
1772                        dropBuilder.append(catSw.toString());
1773                        addErrorToDropBox("lowmem", null, "system_server", null,
1774                                null, tag.toString(), dropBuilder.toString(), null, null);
1775                        //Slog.i(TAG, "Sent to dropbox:");
1776                        //Slog.i(TAG, dropBuilder.toString());
1777                        synchronized (ActivityManagerService.this) {
1778                            long now = SystemClock.uptimeMillis();
1779                            if (mLastMemUsageReportTime < now) {
1780                                mLastMemUsageReportTime = now;
1781                            }
1782                        }
1783                    }
1784                };
1785                thread.start();
1786                break;
1787            }
1788            case START_USER_SWITCH_MSG: {
1789                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1790                break;
1791            }
1792            case REPORT_USER_SWITCH_MSG: {
1793                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1794                break;
1795            }
1796            case CONTINUE_USER_SWITCH_MSG: {
1797                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case USER_SWITCH_TIMEOUT_MSG: {
1801                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1802                break;
1803            }
1804            case IMMERSIVE_MODE_LOCK_MSG: {
1805                final boolean nextState = (msg.arg1 != 0);
1806                if (mUpdateLock.isHeld() != nextState) {
1807                    if (DEBUG_IMMERSIVE) {
1808                        final ActivityRecord r = (ActivityRecord) msg.obj;
1809                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1810                    }
1811                    if (nextState) {
1812                        mUpdateLock.acquire();
1813                    } else {
1814                        mUpdateLock.release();
1815                    }
1816                }
1817                break;
1818            }
1819            case PERSIST_URI_GRANTS_MSG: {
1820                writeGrantedUriPermissions();
1821                break;
1822            }
1823            case REQUEST_ALL_PSS_MSG: {
1824                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1825                break;
1826            }
1827            case START_PROFILES_MSG: {
1828                synchronized (ActivityManagerService.this) {
1829                    startProfilesLocked();
1830                }
1831                break;
1832            }
1833            case UPDATE_TIME: {
1834                synchronized (ActivityManagerService.this) {
1835                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1836                        ProcessRecord r = mLruProcesses.get(i);
1837                        if (r.thread != null) {
1838                            try {
1839                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1840                            } catch (RemoteException ex) {
1841                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1842                            }
1843                        }
1844                    }
1845                }
1846                break;
1847            }
1848            case SYSTEM_USER_START_MSG: {
1849                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1850                        Integer.toString(msg.arg1), msg.arg1);
1851                mSystemServiceManager.startUser(msg.arg1);
1852                break;
1853            }
1854            case SYSTEM_USER_CURRENT_MSG: {
1855                mBatteryStatsService.noteEvent(
1856                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1857                        Integer.toString(msg.arg2), msg.arg2);
1858                mBatteryStatsService.noteEvent(
1859                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1860                        Integer.toString(msg.arg1), msg.arg1);
1861                mSystemServiceManager.switchUser(msg.arg1);
1862                mLockToAppRequest.clearPrompt();
1863                break;
1864            }
1865            case ENTER_ANIMATION_COMPLETE_MSG: {
1866                synchronized (ActivityManagerService.this) {
1867                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1868                    if (r != null && r.app != null && r.app.thread != null) {
1869                        try {
1870                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1871                        } catch (RemoteException e) {
1872                        }
1873                    }
1874                }
1875                break;
1876            }
1877            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1878                enableScreenAfterBoot();
1879                break;
1880            }
1881            }
1882        }
1883    };
1884
1885    static final int COLLECT_PSS_BG_MSG = 1;
1886
1887    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1888        @Override
1889        public void handleMessage(Message msg) {
1890            switch (msg.what) {
1891            case COLLECT_PSS_BG_MSG: {
1892                long start = SystemClock.uptimeMillis();
1893                MemInfoReader memInfo = null;
1894                synchronized (ActivityManagerService.this) {
1895                    if (mFullPssPending) {
1896                        mFullPssPending = false;
1897                        memInfo = new MemInfoReader();
1898                    }
1899                }
1900                if (memInfo != null) {
1901                    updateCpuStatsNow();
1902                    long nativeTotalPss = 0;
1903                    synchronized (mProcessCpuTracker) {
1904                        final int N = mProcessCpuTracker.countStats();
1905                        for (int j=0; j<N; j++) {
1906                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1907                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1908                                // This is definitely an application process; skip it.
1909                                continue;
1910                            }
1911                            synchronized (mPidsSelfLocked) {
1912                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1913                                    // This is one of our own processes; skip it.
1914                                    continue;
1915                                }
1916                            }
1917                            nativeTotalPss += Debug.getPss(st.pid, null);
1918                        }
1919                    }
1920                    memInfo.readMemInfo();
1921                    synchronized (ActivityManagerService.this) {
1922                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1923                                + (SystemClock.uptimeMillis()-start) + "ms");
1924                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1925                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1926                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1927                                        +memInfo.getSlabSizeKb(),
1928                                nativeTotalPss);
1929                    }
1930                }
1931
1932                int i=0, num=0;
1933                long[] tmp = new long[1];
1934                do {
1935                    ProcessRecord proc;
1936                    int procState;
1937                    int pid;
1938                    synchronized (ActivityManagerService.this) {
1939                        if (i >= mPendingPssProcesses.size()) {
1940                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1941                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1942                            mPendingPssProcesses.clear();
1943                            return;
1944                        }
1945                        proc = mPendingPssProcesses.get(i);
1946                        procState = proc.pssProcState;
1947                        if (proc.thread != null && procState == proc.setProcState) {
1948                            pid = proc.pid;
1949                        } else {
1950                            proc = null;
1951                            pid = 0;
1952                        }
1953                        i++;
1954                    }
1955                    if (proc != null) {
1956                        long pss = Debug.getPss(pid, tmp);
1957                        synchronized (ActivityManagerService.this) {
1958                            if (proc.thread != null && proc.setProcState == procState
1959                                    && proc.pid == pid) {
1960                                num++;
1961                                proc.lastPssTime = SystemClock.uptimeMillis();
1962                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1963                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1964                                        + ": " + pss + " lastPss=" + proc.lastPss
1965                                        + " state=" + ProcessList.makeProcStateString(procState));
1966                                if (proc.initialIdlePss == 0) {
1967                                    proc.initialIdlePss = pss;
1968                                }
1969                                proc.lastPss = pss;
1970                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1971                                    proc.lastCachedPss = pss;
1972                                }
1973                            }
1974                        }
1975                    }
1976                } while (true);
1977            }
1978            }
1979        }
1980    };
1981
1982    /**
1983     * Monitor for package changes and update our internal state.
1984     */
1985    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1986        @Override
1987        public void onPackageRemoved(String packageName, int uid) {
1988            // Remove all tasks with activities in the specified package from the list of recent tasks
1989            synchronized (ActivityManagerService.this) {
1990                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1991                    TaskRecord tr = mRecentTasks.get(i);
1992                    ComponentName cn = tr.intent.getComponent();
1993                    if (cn != null && cn.getPackageName().equals(packageName)) {
1994                        // If the package name matches, remove the task and kill the process
1995                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1996                    }
1997                }
1998            }
1999        }
2000
2001        @Override
2002        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2003            onPackageModified(packageName);
2004            return true;
2005        }
2006
2007        @Override
2008        public void onPackageModified(String packageName) {
2009            final PackageManager pm = mContext.getPackageManager();
2010            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2011                    new ArrayList<Pair<Intent, Integer>>();
2012            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2013            // Copy the list of recent tasks so that we don't hold onto the lock on
2014            // ActivityManagerService for long periods while checking if components exist.
2015            synchronized (ActivityManagerService.this) {
2016                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2017                    TaskRecord tr = mRecentTasks.get(i);
2018                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2019                }
2020            }
2021            // Check the recent tasks and filter out all tasks with components that no longer exist.
2022            Intent tmpI = new Intent();
2023            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2024                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2025                ComponentName cn = p.first.getComponent();
2026                if (cn != null && cn.getPackageName().equals(packageName)) {
2027                    try {
2028                        // Add the task to the list to remove if the component no longer exists
2029                        tmpI.setComponent(cn);
2030                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2031                            tasksToRemove.add(p.second);
2032                        }
2033                    } catch (Exception e) {}
2034                }
2035            }
2036            // Prune all the tasks with removed components from the list of recent tasks
2037            synchronized (ActivityManagerService.this) {
2038                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2039                    // Remove the task but don't kill the process (since other components in that
2040                    // package may still be running and in the background)
2041                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2042                }
2043            }
2044        }
2045
2046        @Override
2047        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2048            // Force stop the specified packages
2049            if (packages != null) {
2050                for (String pkg : packages) {
2051                    synchronized (ActivityManagerService.this) {
2052                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2053                                "finished booting")) {
2054                            return true;
2055                        }
2056                    }
2057                }
2058            }
2059            return false;
2060        }
2061    };
2062
2063    public void setSystemProcess() {
2064        try {
2065            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2066            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2067            ServiceManager.addService("meminfo", new MemBinder(this));
2068            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2069            ServiceManager.addService("dbinfo", new DbBinder(this));
2070            if (MONITOR_CPU_USAGE) {
2071                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2072            }
2073            ServiceManager.addService("permission", new PermissionController(this));
2074
2075            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2076                    "android", STOCK_PM_FLAGS);
2077            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2078
2079            synchronized (this) {
2080                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2081                app.persistent = true;
2082                app.pid = MY_PID;
2083                app.maxAdj = ProcessList.SYSTEM_ADJ;
2084                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2085                mProcessNames.put(app.processName, app.uid, app);
2086                synchronized (mPidsSelfLocked) {
2087                    mPidsSelfLocked.put(app.pid, app);
2088                }
2089                updateLruProcessLocked(app, false, null);
2090                updateOomAdjLocked();
2091            }
2092        } catch (PackageManager.NameNotFoundException e) {
2093            throw new RuntimeException(
2094                    "Unable to find android system package", e);
2095        }
2096    }
2097
2098    public void setWindowManager(WindowManagerService wm) {
2099        mWindowManager = wm;
2100        mStackSupervisor.setWindowManager(wm);
2101    }
2102
2103    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2104        mUsageStatsService = usageStatsManager;
2105    }
2106
2107    public void startObservingNativeCrashes() {
2108        final NativeCrashListener ncl = new NativeCrashListener(this);
2109        ncl.start();
2110    }
2111
2112    public IAppOpsService getAppOpsService() {
2113        return mAppOpsService;
2114    }
2115
2116    static class MemBinder extends Binder {
2117        ActivityManagerService mActivityManagerService;
2118        MemBinder(ActivityManagerService activityManagerService) {
2119            mActivityManagerService = activityManagerService;
2120        }
2121
2122        @Override
2123        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2124            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2125                    != PackageManager.PERMISSION_GRANTED) {
2126                pw.println("Permission Denial: can't dump meminfo from from pid="
2127                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2128                        + " without permission " + android.Manifest.permission.DUMP);
2129                return;
2130            }
2131
2132            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2133        }
2134    }
2135
2136    static class GraphicsBinder extends Binder {
2137        ActivityManagerService mActivityManagerService;
2138        GraphicsBinder(ActivityManagerService activityManagerService) {
2139            mActivityManagerService = activityManagerService;
2140        }
2141
2142        @Override
2143        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2144            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2145                    != PackageManager.PERMISSION_GRANTED) {
2146                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2147                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2148                        + " without permission " + android.Manifest.permission.DUMP);
2149                return;
2150            }
2151
2152            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2153        }
2154    }
2155
2156    static class DbBinder extends Binder {
2157        ActivityManagerService mActivityManagerService;
2158        DbBinder(ActivityManagerService activityManagerService) {
2159            mActivityManagerService = activityManagerService;
2160        }
2161
2162        @Override
2163        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2164            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2165                    != PackageManager.PERMISSION_GRANTED) {
2166                pw.println("Permission Denial: can't dump dbinfo from from pid="
2167                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2168                        + " without permission " + android.Manifest.permission.DUMP);
2169                return;
2170            }
2171
2172            mActivityManagerService.dumpDbInfo(fd, pw, args);
2173        }
2174    }
2175
2176    static class CpuBinder extends Binder {
2177        ActivityManagerService mActivityManagerService;
2178        CpuBinder(ActivityManagerService activityManagerService) {
2179            mActivityManagerService = activityManagerService;
2180        }
2181
2182        @Override
2183        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2184            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2185                    != PackageManager.PERMISSION_GRANTED) {
2186                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2187                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2188                        + " without permission " + android.Manifest.permission.DUMP);
2189                return;
2190            }
2191
2192            synchronized (mActivityManagerService.mProcessCpuTracker) {
2193                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2194                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2195                        SystemClock.uptimeMillis()));
2196            }
2197        }
2198    }
2199
2200    public static final class Lifecycle extends SystemService {
2201        private final ActivityManagerService mService;
2202
2203        public Lifecycle(Context context) {
2204            super(context);
2205            mService = new ActivityManagerService(context);
2206        }
2207
2208        @Override
2209        public void onStart() {
2210            mService.start();
2211        }
2212
2213        public ActivityManagerService getService() {
2214            return mService;
2215        }
2216    }
2217
2218    // Note: This method is invoked on the main thread but may need to attach various
2219    // handlers to other threads.  So take care to be explicit about the looper.
2220    public ActivityManagerService(Context systemContext) {
2221        mContext = systemContext;
2222        mFactoryTest = FactoryTest.getMode();
2223        mSystemThread = ActivityThread.currentActivityThread();
2224
2225        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2226
2227        mHandlerThread = new ServiceThread(TAG,
2228                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2229        mHandlerThread.start();
2230        mHandler = new MainHandler(mHandlerThread.getLooper());
2231
2232        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2233                "foreground", BROADCAST_FG_TIMEOUT, false);
2234        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2235                "background", BROADCAST_BG_TIMEOUT, true);
2236        mBroadcastQueues[0] = mFgBroadcastQueue;
2237        mBroadcastQueues[1] = mBgBroadcastQueue;
2238
2239        mServices = new ActiveServices(this);
2240        mProviderMap = new ProviderMap(this);
2241
2242        // TODO: Move creation of battery stats service outside of activity manager service.
2243        File dataDir = Environment.getDataDirectory();
2244        File systemDir = new File(dataDir, "system");
2245        systemDir.mkdirs();
2246        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2247        mBatteryStatsService.getActiveStatistics().readLocked();
2248        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2249        mOnBattery = DEBUG_POWER ? true
2250                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2251        mBatteryStatsService.getActiveStatistics().setCallback(this);
2252
2253        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2254
2255        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2256
2257        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2258
2259        // User 0 is the first and only user that runs at boot.
2260        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2261        mUserLru.add(Integer.valueOf(0));
2262        updateStartedUserArrayLocked();
2263
2264        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2265            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2266
2267        mConfiguration.setToDefaults();
2268        mConfiguration.setLocale(Locale.getDefault());
2269
2270        mConfigurationSeq = mConfiguration.seq = 1;
2271        mProcessCpuTracker.init();
2272
2273        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2274        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2275        mStackSupervisor = new ActivityStackSupervisor(this);
2276        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2277
2278        mProcessCpuThread = new Thread("CpuTracker") {
2279            @Override
2280            public void run() {
2281                while (true) {
2282                    try {
2283                        try {
2284                            synchronized(this) {
2285                                final long now = SystemClock.uptimeMillis();
2286                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2287                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2288                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2289                                //        + ", write delay=" + nextWriteDelay);
2290                                if (nextWriteDelay < nextCpuDelay) {
2291                                    nextCpuDelay = nextWriteDelay;
2292                                }
2293                                if (nextCpuDelay > 0) {
2294                                    mProcessCpuMutexFree.set(true);
2295                                    this.wait(nextCpuDelay);
2296                                }
2297                            }
2298                        } catch (InterruptedException e) {
2299                        }
2300                        updateCpuStatsNow();
2301                    } catch (Exception e) {
2302                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2303                    }
2304                }
2305            }
2306        };
2307
2308        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2309
2310        Watchdog.getInstance().addMonitor(this);
2311        Watchdog.getInstance().addThread(mHandler);
2312    }
2313
2314    public void setSystemServiceManager(SystemServiceManager mgr) {
2315        mSystemServiceManager = mgr;
2316    }
2317
2318    private void start() {
2319        Process.removeAllProcessGroups();
2320        mProcessCpuThread.start();
2321
2322        mBatteryStatsService.publish(mContext);
2323        mAppOpsService.publish(mContext);
2324        Slog.d("AppOps", "AppOpsService published");
2325        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2326    }
2327
2328    public void initPowerManagement() {
2329        mStackSupervisor.initPowerManagement();
2330        mBatteryStatsService.initPowerManagement();
2331    }
2332
2333    @Override
2334    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2335            throws RemoteException {
2336        if (code == SYSPROPS_TRANSACTION) {
2337            // We need to tell all apps about the system property change.
2338            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2339            synchronized(this) {
2340                final int NP = mProcessNames.getMap().size();
2341                for (int ip=0; ip<NP; ip++) {
2342                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2343                    final int NA = apps.size();
2344                    for (int ia=0; ia<NA; ia++) {
2345                        ProcessRecord app = apps.valueAt(ia);
2346                        if (app.thread != null) {
2347                            procs.add(app.thread.asBinder());
2348                        }
2349                    }
2350                }
2351            }
2352
2353            int N = procs.size();
2354            for (int i=0; i<N; i++) {
2355                Parcel data2 = Parcel.obtain();
2356                try {
2357                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2358                } catch (RemoteException e) {
2359                }
2360                data2.recycle();
2361            }
2362        }
2363        try {
2364            return super.onTransact(code, data, reply, flags);
2365        } catch (RuntimeException e) {
2366            // The activity manager only throws security exceptions, so let's
2367            // log all others.
2368            if (!(e instanceof SecurityException)) {
2369                Slog.wtf(TAG, "Activity Manager Crash", e);
2370            }
2371            throw e;
2372        }
2373    }
2374
2375    void updateCpuStats() {
2376        final long now = SystemClock.uptimeMillis();
2377        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2378            return;
2379        }
2380        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2381            synchronized (mProcessCpuThread) {
2382                mProcessCpuThread.notify();
2383            }
2384        }
2385    }
2386
2387    void updateCpuStatsNow() {
2388        synchronized (mProcessCpuTracker) {
2389            mProcessCpuMutexFree.set(false);
2390            final long now = SystemClock.uptimeMillis();
2391            boolean haveNewCpuStats = false;
2392
2393            if (MONITOR_CPU_USAGE &&
2394                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2395                mLastCpuTime.set(now);
2396                haveNewCpuStats = true;
2397                mProcessCpuTracker.update();
2398                //Slog.i(TAG, mProcessCpu.printCurrentState());
2399                //Slog.i(TAG, "Total CPU usage: "
2400                //        + mProcessCpu.getTotalCpuPercent() + "%");
2401
2402                // Slog the cpu usage if the property is set.
2403                if ("true".equals(SystemProperties.get("events.cpu"))) {
2404                    int user = mProcessCpuTracker.getLastUserTime();
2405                    int system = mProcessCpuTracker.getLastSystemTime();
2406                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2407                    int irq = mProcessCpuTracker.getLastIrqTime();
2408                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2409                    int idle = mProcessCpuTracker.getLastIdleTime();
2410
2411                    int total = user + system + iowait + irq + softIrq + idle;
2412                    if (total == 0) total = 1;
2413
2414                    EventLog.writeEvent(EventLogTags.CPU,
2415                            ((user+system+iowait+irq+softIrq) * 100) / total,
2416                            (user * 100) / total,
2417                            (system * 100) / total,
2418                            (iowait * 100) / total,
2419                            (irq * 100) / total,
2420                            (softIrq * 100) / total);
2421                }
2422            }
2423
2424            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2425            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2426            synchronized(bstats) {
2427                synchronized(mPidsSelfLocked) {
2428                    if (haveNewCpuStats) {
2429                        if (mOnBattery) {
2430                            int perc = bstats.startAddingCpuLocked();
2431                            int totalUTime = 0;
2432                            int totalSTime = 0;
2433                            final int N = mProcessCpuTracker.countStats();
2434                            for (int i=0; i<N; i++) {
2435                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2436                                if (!st.working) {
2437                                    continue;
2438                                }
2439                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2440                                int otherUTime = (st.rel_utime*perc)/100;
2441                                int otherSTime = (st.rel_stime*perc)/100;
2442                                totalUTime += otherUTime;
2443                                totalSTime += otherSTime;
2444                                if (pr != null) {
2445                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2446                                    if (ps == null || !ps.isActive()) {
2447                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2448                                                pr.info.uid, pr.processName);
2449                                    }
2450                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2451                                            st.rel_stime-otherSTime);
2452                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2453                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2454                                } else {
2455                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2456                                    if (ps == null || !ps.isActive()) {
2457                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2458                                                bstats.mapUid(st.uid), st.name);
2459                                    }
2460                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2461                                            st.rel_stime-otherSTime);
2462                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2463                                }
2464                            }
2465                            bstats.finishAddingCpuLocked(perc, totalUTime,
2466                                    totalSTime, cpuSpeedTimes);
2467                        }
2468                    }
2469                }
2470
2471                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2472                    mLastWriteTime = now;
2473                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2474                }
2475            }
2476        }
2477    }
2478
2479    @Override
2480    public void batteryNeedsCpuUpdate() {
2481        updateCpuStatsNow();
2482    }
2483
2484    @Override
2485    public void batteryPowerChanged(boolean onBattery) {
2486        // When plugging in, update the CPU stats first before changing
2487        // the plug state.
2488        updateCpuStatsNow();
2489        synchronized (this) {
2490            synchronized(mPidsSelfLocked) {
2491                mOnBattery = DEBUG_POWER ? true : onBattery;
2492            }
2493        }
2494    }
2495
2496    /**
2497     * Initialize the application bind args. These are passed to each
2498     * process when the bindApplication() IPC is sent to the process. They're
2499     * lazily setup to make sure the services are running when they're asked for.
2500     */
2501    private HashMap<String, IBinder> getCommonServicesLocked() {
2502        if (mAppBindArgs == null) {
2503            mAppBindArgs = new HashMap<String, IBinder>();
2504
2505            // Setup the application init args
2506            mAppBindArgs.put("package", ServiceManager.getService("package"));
2507            mAppBindArgs.put("window", ServiceManager.getService("window"));
2508            mAppBindArgs.put(Context.ALARM_SERVICE,
2509                    ServiceManager.getService(Context.ALARM_SERVICE));
2510        }
2511        return mAppBindArgs;
2512    }
2513
2514    final void setFocusedActivityLocked(ActivityRecord r) {
2515        if (mFocusedActivity != r) {
2516            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2517            mFocusedActivity = r;
2518            if (r.task != null && r.task.voiceInteractor != null) {
2519                startRunningVoiceLocked();
2520            } else {
2521                finishRunningVoiceLocked();
2522            }
2523            mStackSupervisor.setFocusedStack(r);
2524            if (r != null) {
2525                mWindowManager.setFocusedApp(r.appToken, true);
2526            }
2527            applyUpdateLockStateLocked(r);
2528        }
2529    }
2530
2531    final void clearFocusedActivity(ActivityRecord r) {
2532        if (mFocusedActivity == r) {
2533            mFocusedActivity = null;
2534        }
2535    }
2536
2537    @Override
2538    public void setFocusedStack(int stackId) {
2539        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2540        synchronized (ActivityManagerService.this) {
2541            ActivityStack stack = mStackSupervisor.getStack(stackId);
2542            if (stack != null) {
2543                ActivityRecord r = stack.topRunningActivityLocked(null);
2544                if (r != null) {
2545                    setFocusedActivityLocked(r);
2546                }
2547            }
2548        }
2549    }
2550
2551    @Override
2552    public void notifyActivityDrawn(IBinder token) {
2553        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2554        synchronized (this) {
2555            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2556            if (r != null) {
2557                r.task.stack.notifyActivityDrawnLocked(r);
2558            }
2559        }
2560    }
2561
2562    final void applyUpdateLockStateLocked(ActivityRecord r) {
2563        // Modifications to the UpdateLock state are done on our handler, outside
2564        // the activity manager's locks.  The new state is determined based on the
2565        // state *now* of the relevant activity record.  The object is passed to
2566        // the handler solely for logging detail, not to be consulted/modified.
2567        final boolean nextState = r != null && r.immersive;
2568        mHandler.sendMessage(
2569                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2570    }
2571
2572    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2573        Message msg = Message.obtain();
2574        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2575        msg.obj = r.task.askedCompatMode ? null : r;
2576        mHandler.sendMessage(msg);
2577    }
2578
2579    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2580            String what, Object obj, ProcessRecord srcApp) {
2581        app.lastActivityTime = now;
2582
2583        if (app.activities.size() > 0) {
2584            // Don't want to touch dependent processes that are hosting activities.
2585            return index;
2586        }
2587
2588        int lrui = mLruProcesses.lastIndexOf(app);
2589        if (lrui < 0) {
2590            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2591                    + what + " " + obj + " from " + srcApp);
2592            return index;
2593        }
2594
2595        if (lrui >= index) {
2596            // Don't want to cause this to move dependent processes *back* in the
2597            // list as if they were less frequently used.
2598            return index;
2599        }
2600
2601        if (lrui >= mLruProcessActivityStart) {
2602            // Don't want to touch dependent processes that are hosting activities.
2603            return index;
2604        }
2605
2606        mLruProcesses.remove(lrui);
2607        if (index > 0) {
2608            index--;
2609        }
2610        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2611                + " in LRU list: " + app);
2612        mLruProcesses.add(index, app);
2613        return index;
2614    }
2615
2616    final void removeLruProcessLocked(ProcessRecord app) {
2617        int lrui = mLruProcesses.lastIndexOf(app);
2618        if (lrui >= 0) {
2619            if (lrui <= mLruProcessActivityStart) {
2620                mLruProcessActivityStart--;
2621            }
2622            if (lrui <= mLruProcessServiceStart) {
2623                mLruProcessServiceStart--;
2624            }
2625            mLruProcesses.remove(lrui);
2626        }
2627    }
2628
2629    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2630            ProcessRecord client) {
2631        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2632                || app.treatLikeActivity;
2633        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2634        if (!activityChange && hasActivity) {
2635            // The process has activities, so we are only allowing activity-based adjustments
2636            // to move it.  It should be kept in the front of the list with other
2637            // processes that have activities, and we don't want those to change their
2638            // order except due to activity operations.
2639            return;
2640        }
2641
2642        mLruSeq++;
2643        final long now = SystemClock.uptimeMillis();
2644        app.lastActivityTime = now;
2645
2646        // First a quick reject: if the app is already at the position we will
2647        // put it, then there is nothing to do.
2648        if (hasActivity) {
2649            final int N = mLruProcesses.size();
2650            if (N > 0 && mLruProcesses.get(N-1) == app) {
2651                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2652                return;
2653            }
2654        } else {
2655            if (mLruProcessServiceStart > 0
2656                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2657                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2658                return;
2659            }
2660        }
2661
2662        int lrui = mLruProcesses.lastIndexOf(app);
2663
2664        if (app.persistent && lrui >= 0) {
2665            // We don't care about the position of persistent processes, as long as
2666            // they are in the list.
2667            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2668            return;
2669        }
2670
2671        /* In progress: compute new position first, so we can avoid doing work
2672           if the process is not actually going to move.  Not yet working.
2673        int addIndex;
2674        int nextIndex;
2675        boolean inActivity = false, inService = false;
2676        if (hasActivity) {
2677            // Process has activities, put it at the very tipsy-top.
2678            addIndex = mLruProcesses.size();
2679            nextIndex = mLruProcessServiceStart;
2680            inActivity = true;
2681        } else if (hasService) {
2682            // Process has services, put it at the top of the service list.
2683            addIndex = mLruProcessActivityStart;
2684            nextIndex = mLruProcessServiceStart;
2685            inActivity = true;
2686            inService = true;
2687        } else  {
2688            // Process not otherwise of interest, it goes to the top of the non-service area.
2689            addIndex = mLruProcessServiceStart;
2690            if (client != null) {
2691                int clientIndex = mLruProcesses.lastIndexOf(client);
2692                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2693                        + app);
2694                if (clientIndex >= 0 && addIndex > clientIndex) {
2695                    addIndex = clientIndex;
2696                }
2697            }
2698            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2699        }
2700
2701        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2702                + mLruProcessActivityStart + "): " + app);
2703        */
2704
2705        if (lrui >= 0) {
2706            if (lrui < mLruProcessActivityStart) {
2707                mLruProcessActivityStart--;
2708            }
2709            if (lrui < mLruProcessServiceStart) {
2710                mLruProcessServiceStart--;
2711            }
2712            /*
2713            if (addIndex > lrui) {
2714                addIndex--;
2715            }
2716            if (nextIndex > lrui) {
2717                nextIndex--;
2718            }
2719            */
2720            mLruProcesses.remove(lrui);
2721        }
2722
2723        /*
2724        mLruProcesses.add(addIndex, app);
2725        if (inActivity) {
2726            mLruProcessActivityStart++;
2727        }
2728        if (inService) {
2729            mLruProcessActivityStart++;
2730        }
2731        */
2732
2733        int nextIndex;
2734        if (hasActivity) {
2735            final int N = mLruProcesses.size();
2736            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2737                // Process doesn't have activities, but has clients with
2738                // activities...  move it up, but one below the top (the top
2739                // should always have a real activity).
2740                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2741                mLruProcesses.add(N-1, app);
2742                // To keep it from spamming the LRU list (by making a bunch of clients),
2743                // we will push down any other entries owned by the app.
2744                final int uid = app.info.uid;
2745                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2746                    ProcessRecord subProc = mLruProcesses.get(i);
2747                    if (subProc.info.uid == uid) {
2748                        // We want to push this one down the list.  If the process after
2749                        // it is for the same uid, however, don't do so, because we don't
2750                        // want them internally to be re-ordered.
2751                        if (mLruProcesses.get(i-1).info.uid != uid) {
2752                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2753                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2754                            ProcessRecord tmp = mLruProcesses.get(i);
2755                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2756                            mLruProcesses.set(i-1, tmp);
2757                            i--;
2758                        }
2759                    } else {
2760                        // A gap, we can stop here.
2761                        break;
2762                    }
2763                }
2764            } else {
2765                // Process has activities, put it at the very tipsy-top.
2766                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2767                mLruProcesses.add(app);
2768            }
2769            nextIndex = mLruProcessServiceStart;
2770        } else if (hasService) {
2771            // Process has services, put it at the top of the service list.
2772            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2773            mLruProcesses.add(mLruProcessActivityStart, app);
2774            nextIndex = mLruProcessServiceStart;
2775            mLruProcessActivityStart++;
2776        } else  {
2777            // Process not otherwise of interest, it goes to the top of the non-service area.
2778            int index = mLruProcessServiceStart;
2779            if (client != null) {
2780                // If there is a client, don't allow the process to be moved up higher
2781                // in the list than that client.
2782                int clientIndex = mLruProcesses.lastIndexOf(client);
2783                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2784                        + " when updating " + app);
2785                if (clientIndex <= lrui) {
2786                    // Don't allow the client index restriction to push it down farther in the
2787                    // list than it already is.
2788                    clientIndex = lrui;
2789                }
2790                if (clientIndex >= 0 && index > clientIndex) {
2791                    index = clientIndex;
2792                }
2793            }
2794            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2795            mLruProcesses.add(index, app);
2796            nextIndex = index-1;
2797            mLruProcessActivityStart++;
2798            mLruProcessServiceStart++;
2799        }
2800
2801        // If the app is currently using a content provider or service,
2802        // bump those processes as well.
2803        for (int j=app.connections.size()-1; j>=0; j--) {
2804            ConnectionRecord cr = app.connections.valueAt(j);
2805            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2806                    && cr.binding.service.app != null
2807                    && cr.binding.service.app.lruSeq != mLruSeq
2808                    && !cr.binding.service.app.persistent) {
2809                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2810                        "service connection", cr, app);
2811            }
2812        }
2813        for (int j=app.conProviders.size()-1; j>=0; j--) {
2814            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2815            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2816                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2817                        "provider reference", cpr, app);
2818            }
2819        }
2820    }
2821
2822    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2823        if (uid == Process.SYSTEM_UID) {
2824            // The system gets to run in any process.  If there are multiple
2825            // processes with the same uid, just pick the first (this
2826            // should never happen).
2827            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2828            if (procs == null) return null;
2829            final int N = procs.size();
2830            for (int i = 0; i < N; i++) {
2831                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2832            }
2833        }
2834        ProcessRecord proc = mProcessNames.get(processName, uid);
2835        if (false && proc != null && !keepIfLarge
2836                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2837                && proc.lastCachedPss >= 4000) {
2838            // Turn this condition on to cause killing to happen regularly, for testing.
2839            if (proc.baseProcessTracker != null) {
2840                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2841            }
2842            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2843        } else if (proc != null && !keepIfLarge
2844                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2845                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2846            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2847            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2848                if (proc.baseProcessTracker != null) {
2849                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2850                }
2851                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2852            }
2853        }
2854        return proc;
2855    }
2856
2857    void ensurePackageDexOpt(String packageName) {
2858        IPackageManager pm = AppGlobals.getPackageManager();
2859        try {
2860            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2861                mDidDexOpt = true;
2862            }
2863        } catch (RemoteException e) {
2864        }
2865    }
2866
2867    boolean isNextTransitionForward() {
2868        int transit = mWindowManager.getPendingAppTransition();
2869        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2870                || transit == AppTransition.TRANSIT_TASK_OPEN
2871                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2872    }
2873
2874    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2875            String processName, String abiOverride, int uid, Runnable crashHandler) {
2876        synchronized(this) {
2877            ApplicationInfo info = new ApplicationInfo();
2878            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2879            // For isolated processes, the former contains the parent's uid and the latter the
2880            // actual uid of the isolated process.
2881            // In the special case introduced by this method (which is, starting an isolated
2882            // process directly from the SystemServer without an actual parent app process) the
2883            // closest thing to a parent's uid is SYSTEM_UID.
2884            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2885            // the |isolated| logic in the ProcessRecord constructor.
2886            info.uid = Process.SYSTEM_UID;
2887            info.processName = processName;
2888            info.className = entryPoint;
2889            info.packageName = "android";
2890            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2891                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2892                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2893                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2894                    crashHandler);
2895            return proc != null ? proc.pid : 0;
2896        }
2897    }
2898
2899    final ProcessRecord startProcessLocked(String processName,
2900            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2901            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2902            boolean isolated, boolean keepIfLarge) {
2903        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2904                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2905                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2906                null /* crashHandler */);
2907    }
2908
2909    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2910            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2911            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2912            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2913        long startTime = SystemClock.elapsedRealtime();
2914        ProcessRecord app;
2915        if (!isolated) {
2916            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2917            checkTime(startTime, "startProcess: after getProcessRecord");
2918        } else {
2919            // If this is an isolated process, it can't re-use an existing process.
2920            app = null;
2921        }
2922        // We don't have to do anything more if:
2923        // (1) There is an existing application record; and
2924        // (2) The caller doesn't think it is dead, OR there is no thread
2925        //     object attached to it so we know it couldn't have crashed; and
2926        // (3) There is a pid assigned to it, so it is either starting or
2927        //     already running.
2928        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2929                + " app=" + app + " knownToBeDead=" + knownToBeDead
2930                + " thread=" + (app != null ? app.thread : null)
2931                + " pid=" + (app != null ? app.pid : -1));
2932        if (app != null && app.pid > 0) {
2933            if (!knownToBeDead || app.thread == null) {
2934                // We already have the app running, or are waiting for it to
2935                // come up (we have a pid but not yet its thread), so keep it.
2936                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2937                // If this is a new package in the process, add the package to the list
2938                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2939                checkTime(startTime, "startProcess: done, added package to proc");
2940                return app;
2941            }
2942
2943            // An application record is attached to a previous process,
2944            // clean it up now.
2945            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2946            checkTime(startTime, "startProcess: bad proc running, killing");
2947            Process.killProcessGroup(app.info.uid, app.pid);
2948            handleAppDiedLocked(app, true, true);
2949            checkTime(startTime, "startProcess: done killing old proc");
2950        }
2951
2952        String hostingNameStr = hostingName != null
2953                ? hostingName.flattenToShortString() : null;
2954
2955        if (!isolated) {
2956            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2957                // If we are in the background, then check to see if this process
2958                // is bad.  If so, we will just silently fail.
2959                if (mBadProcesses.get(info.processName, info.uid) != null) {
2960                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2961                            + "/" + info.processName);
2962                    return null;
2963                }
2964            } else {
2965                // When the user is explicitly starting a process, then clear its
2966                // crash count so that we won't make it bad until they see at
2967                // least one crash dialog again, and make the process good again
2968                // if it had been bad.
2969                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2970                        + "/" + info.processName);
2971                mProcessCrashTimes.remove(info.processName, info.uid);
2972                if (mBadProcesses.get(info.processName, info.uid) != null) {
2973                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2974                            UserHandle.getUserId(info.uid), info.uid,
2975                            info.processName);
2976                    mBadProcesses.remove(info.processName, info.uid);
2977                    if (app != null) {
2978                        app.bad = false;
2979                    }
2980                }
2981            }
2982        }
2983
2984        if (app == null) {
2985            checkTime(startTime, "startProcess: creating new process record");
2986            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2987            app.crashHandler = crashHandler;
2988            if (app == null) {
2989                Slog.w(TAG, "Failed making new process record for "
2990                        + processName + "/" + info.uid + " isolated=" + isolated);
2991                return null;
2992            }
2993            mProcessNames.put(processName, app.uid, app);
2994            if (isolated) {
2995                mIsolatedProcesses.put(app.uid, app);
2996            }
2997            checkTime(startTime, "startProcess: done creating new process record");
2998        } else {
2999            // If this is a new package in the process, add the package to the list
3000            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3001            checkTime(startTime, "startProcess: added package to existing proc");
3002        }
3003
3004        // If the system is not ready yet, then hold off on starting this
3005        // process until it is.
3006        if (!mProcessesReady
3007                && !isAllowedWhileBooting(info)
3008                && !allowWhileBooting) {
3009            if (!mProcessesOnHold.contains(app)) {
3010                mProcessesOnHold.add(app);
3011            }
3012            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3013            checkTime(startTime, "startProcess: returning with proc on hold");
3014            return app;
3015        }
3016
3017        checkTime(startTime, "startProcess: stepping in to startProcess");
3018        startProcessLocked(
3019                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3020        checkTime(startTime, "startProcess: done starting proc!");
3021        return (app.pid != 0) ? app : null;
3022    }
3023
3024    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3025        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3026    }
3027
3028    private final void startProcessLocked(ProcessRecord app,
3029            String hostingType, String hostingNameStr) {
3030        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3031                null /* entryPoint */, null /* entryPointArgs */);
3032    }
3033
3034    private final void startProcessLocked(ProcessRecord app, String hostingType,
3035            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3036        long startTime = SystemClock.elapsedRealtime();
3037        if (app.pid > 0 && app.pid != MY_PID) {
3038            checkTime(startTime, "startProcess: removing from pids map");
3039            synchronized (mPidsSelfLocked) {
3040                mPidsSelfLocked.remove(app.pid);
3041                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3042            }
3043            checkTime(startTime, "startProcess: done removing from pids map");
3044            app.setPid(0);
3045        }
3046
3047        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3048                "startProcessLocked removing on hold: " + app);
3049        mProcessesOnHold.remove(app);
3050
3051        checkTime(startTime, "startProcess: starting to update cpu stats");
3052        updateCpuStats();
3053        checkTime(startTime, "startProcess: done updating cpu stats");
3054
3055        try {
3056            int uid = app.uid;
3057
3058            int[] gids = null;
3059            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3060            if (!app.isolated) {
3061                int[] permGids = null;
3062                try {
3063                    checkTime(startTime, "startProcess: getting gids from package manager");
3064                    final PackageManager pm = mContext.getPackageManager();
3065                    permGids = pm.getPackageGids(app.info.packageName);
3066
3067                    if (Environment.isExternalStorageEmulated()) {
3068                        checkTime(startTime, "startProcess: checking external storage perm");
3069                        if (pm.checkPermission(
3070                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3071                                app.info.packageName) == PERMISSION_GRANTED) {
3072                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3073                        } else {
3074                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3075                        }
3076                    }
3077                } catch (PackageManager.NameNotFoundException e) {
3078                    Slog.w(TAG, "Unable to retrieve gids", e);
3079                }
3080
3081                /*
3082                 * Add shared application and profile GIDs so applications can share some
3083                 * resources like shared libraries and access user-wide resources
3084                 */
3085                if (permGids == null) {
3086                    gids = new int[2];
3087                } else {
3088                    gids = new int[permGids.length + 2];
3089                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3090                }
3091                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3092                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3093            }
3094            checkTime(startTime, "startProcess: building args");
3095            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3096                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3097                        && mTopComponent != null
3098                        && app.processName.equals(mTopComponent.getPackageName())) {
3099                    uid = 0;
3100                }
3101                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3102                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3103                    uid = 0;
3104                }
3105            }
3106            int debugFlags = 0;
3107            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3108                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3109                // Also turn on CheckJNI for debuggable apps. It's quite
3110                // awkward to turn on otherwise.
3111                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3112            }
3113            // Run the app in safe mode if its manifest requests so or the
3114            // system is booted in safe mode.
3115            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3116                mSafeMode == true) {
3117                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3118            }
3119            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3120                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3121            }
3122            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3123                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3124            }
3125            if ("1".equals(SystemProperties.get("debug.assert"))) {
3126                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3127            }
3128
3129            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3130            if (requiredAbi == null) {
3131                requiredAbi = Build.SUPPORTED_ABIS[0];
3132            }
3133
3134            String instructionSet = null;
3135            if (app.info.primaryCpuAbi != null) {
3136                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3137            }
3138
3139            // Start the process.  It will either succeed and return a result containing
3140            // the PID of the new process, or else throw a RuntimeException.
3141            boolean isActivityProcess = (entryPoint == null);
3142            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3143            checkTime(startTime, "startProcess: asking zygote to start proc");
3144            Process.ProcessStartResult startResult = Process.start(entryPoint,
3145                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3146                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3147                    entryPointArgs);
3148            checkTime(startTime, "startProcess: returned from zygote!");
3149
3150            if (app.isolated) {
3151                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3152            }
3153            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3154            checkTime(startTime, "startProcess: done updating battery stats");
3155
3156            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3157                    UserHandle.getUserId(uid), startResult.pid, uid,
3158                    app.processName, hostingType,
3159                    hostingNameStr != null ? hostingNameStr : "");
3160
3161            if (app.persistent) {
3162                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3163            }
3164
3165            checkTime(startTime, "startProcess: building log message");
3166            StringBuilder buf = mStringBuilder;
3167            buf.setLength(0);
3168            buf.append("Start proc ");
3169            buf.append(app.processName);
3170            if (!isActivityProcess) {
3171                buf.append(" [");
3172                buf.append(entryPoint);
3173                buf.append("]");
3174            }
3175            buf.append(" for ");
3176            buf.append(hostingType);
3177            if (hostingNameStr != null) {
3178                buf.append(" ");
3179                buf.append(hostingNameStr);
3180            }
3181            buf.append(": pid=");
3182            buf.append(startResult.pid);
3183            buf.append(" uid=");
3184            buf.append(uid);
3185            buf.append(" gids={");
3186            if (gids != null) {
3187                for (int gi=0; gi<gids.length; gi++) {
3188                    if (gi != 0) buf.append(", ");
3189                    buf.append(gids[gi]);
3190
3191                }
3192            }
3193            buf.append("}");
3194            if (requiredAbi != null) {
3195                buf.append(" abi=");
3196                buf.append(requiredAbi);
3197            }
3198            Slog.i(TAG, buf.toString());
3199            app.setPid(startResult.pid);
3200            app.usingWrapper = startResult.usingWrapper;
3201            app.removed = false;
3202            app.killedByAm = false;
3203            checkTime(startTime, "startProcess: starting to update pids map");
3204            synchronized (mPidsSelfLocked) {
3205                this.mPidsSelfLocked.put(startResult.pid, app);
3206                if (isActivityProcess) {
3207                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3208                    msg.obj = app;
3209                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3210                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3211                }
3212            }
3213            checkTime(startTime, "startProcess: done updating pids map");
3214        } catch (RuntimeException e) {
3215            // XXX do better error recovery.
3216            app.setPid(0);
3217            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3218            if (app.isolated) {
3219                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3220            }
3221            Slog.e(TAG, "Failure starting process " + app.processName, e);
3222        }
3223    }
3224
3225    void updateUsageStats(ActivityRecord component, boolean resumed) {
3226        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3227        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3228        if (resumed) {
3229            if (mUsageStatsService != null) {
3230                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3231                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3232            }
3233            synchronized (stats) {
3234                stats.noteActivityResumedLocked(component.app.uid);
3235            }
3236        } else {
3237            if (mUsageStatsService != null) {
3238                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3239                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3240            }
3241            synchronized (stats) {
3242                stats.noteActivityPausedLocked(component.app.uid);
3243            }
3244        }
3245    }
3246
3247    Intent getHomeIntent() {
3248        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3249        intent.setComponent(mTopComponent);
3250        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3251            intent.addCategory(Intent.CATEGORY_HOME);
3252        }
3253        return intent;
3254    }
3255
3256    boolean startHomeActivityLocked(int userId) {
3257        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3258                && mTopAction == null) {
3259            // We are running in factory test mode, but unable to find
3260            // the factory test app, so just sit around displaying the
3261            // error message and don't try to start anything.
3262            return false;
3263        }
3264        Intent intent = getHomeIntent();
3265        ActivityInfo aInfo =
3266            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3267        if (aInfo != null) {
3268            intent.setComponent(new ComponentName(
3269                    aInfo.applicationInfo.packageName, aInfo.name));
3270            // Don't do this if the home app is currently being
3271            // instrumented.
3272            aInfo = new ActivityInfo(aInfo);
3273            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3274            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3275                    aInfo.applicationInfo.uid, true);
3276            if (app == null || app.instrumentationClass == null) {
3277                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3278                mStackSupervisor.startHomeActivity(intent, aInfo);
3279            }
3280        }
3281
3282        return true;
3283    }
3284
3285    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3286        ActivityInfo ai = null;
3287        ComponentName comp = intent.getComponent();
3288        try {
3289            if (comp != null) {
3290                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3291            } else {
3292                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3293                        intent,
3294                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3295                            flags, userId);
3296
3297                if (info != null) {
3298                    ai = info.activityInfo;
3299                }
3300            }
3301        } catch (RemoteException e) {
3302            // ignore
3303        }
3304
3305        return ai;
3306    }
3307
3308    /**
3309     * Starts the "new version setup screen" if appropriate.
3310     */
3311    void startSetupActivityLocked() {
3312        // Only do this once per boot.
3313        if (mCheckedForSetup) {
3314            return;
3315        }
3316
3317        // We will show this screen if the current one is a different
3318        // version than the last one shown, and we are not running in
3319        // low-level factory test mode.
3320        final ContentResolver resolver = mContext.getContentResolver();
3321        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3322                Settings.Global.getInt(resolver,
3323                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3324            mCheckedForSetup = true;
3325
3326            // See if we should be showing the platform update setup UI.
3327            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3328            List<ResolveInfo> ris = mContext.getPackageManager()
3329                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3330
3331            // We don't allow third party apps to replace this.
3332            ResolveInfo ri = null;
3333            for (int i=0; ris != null && i<ris.size(); i++) {
3334                if ((ris.get(i).activityInfo.applicationInfo.flags
3335                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3336                    ri = ris.get(i);
3337                    break;
3338                }
3339            }
3340
3341            if (ri != null) {
3342                String vers = ri.activityInfo.metaData != null
3343                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3344                        : null;
3345                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3346                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3347                            Intent.METADATA_SETUP_VERSION);
3348                }
3349                String lastVers = Settings.Secure.getString(
3350                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3351                if (vers != null && !vers.equals(lastVers)) {
3352                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3353                    intent.setComponent(new ComponentName(
3354                            ri.activityInfo.packageName, ri.activityInfo.name));
3355                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3356                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3357                            null);
3358                }
3359            }
3360        }
3361    }
3362
3363    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3364        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3365    }
3366
3367    void enforceNotIsolatedCaller(String caller) {
3368        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3369            throw new SecurityException("Isolated process not allowed to call " + caller);
3370        }
3371    }
3372
3373    void enforceShellRestriction(String restriction, int userHandle) {
3374        if (Binder.getCallingUid() == Process.SHELL_UID) {
3375            if (userHandle < 0
3376                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3377                throw new SecurityException("Shell does not have permission to access user "
3378                        + userHandle);
3379            }
3380        }
3381    }
3382
3383    @Override
3384    public int getFrontActivityScreenCompatMode() {
3385        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3386        synchronized (this) {
3387            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3388        }
3389    }
3390
3391    @Override
3392    public void setFrontActivityScreenCompatMode(int mode) {
3393        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3394                "setFrontActivityScreenCompatMode");
3395        synchronized (this) {
3396            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3397        }
3398    }
3399
3400    @Override
3401    public int getPackageScreenCompatMode(String packageName) {
3402        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3403        synchronized (this) {
3404            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3405        }
3406    }
3407
3408    @Override
3409    public void setPackageScreenCompatMode(String packageName, int mode) {
3410        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3411                "setPackageScreenCompatMode");
3412        synchronized (this) {
3413            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3414        }
3415    }
3416
3417    @Override
3418    public boolean getPackageAskScreenCompat(String packageName) {
3419        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3420        synchronized (this) {
3421            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3422        }
3423    }
3424
3425    @Override
3426    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3427        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3428                "setPackageAskScreenCompat");
3429        synchronized (this) {
3430            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3431        }
3432    }
3433
3434    private void dispatchProcessesChanged() {
3435        int N;
3436        synchronized (this) {
3437            N = mPendingProcessChanges.size();
3438            if (mActiveProcessChanges.length < N) {
3439                mActiveProcessChanges = new ProcessChangeItem[N];
3440            }
3441            mPendingProcessChanges.toArray(mActiveProcessChanges);
3442            mAvailProcessChanges.addAll(mPendingProcessChanges);
3443            mPendingProcessChanges.clear();
3444            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3445        }
3446
3447        int i = mProcessObservers.beginBroadcast();
3448        while (i > 0) {
3449            i--;
3450            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3451            if (observer != null) {
3452                try {
3453                    for (int j=0; j<N; j++) {
3454                        ProcessChangeItem item = mActiveProcessChanges[j];
3455                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3456                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3457                                    + item.pid + " uid=" + item.uid + ": "
3458                                    + item.foregroundActivities);
3459                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3460                                    item.foregroundActivities);
3461                        }
3462                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3463                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3464                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3465                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3466                        }
3467                    }
3468                } catch (RemoteException e) {
3469                }
3470            }
3471        }
3472        mProcessObservers.finishBroadcast();
3473    }
3474
3475    private void dispatchProcessDied(int pid, int uid) {
3476        int i = mProcessObservers.beginBroadcast();
3477        while (i > 0) {
3478            i--;
3479            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3480            if (observer != null) {
3481                try {
3482                    observer.onProcessDied(pid, uid);
3483                } catch (RemoteException e) {
3484                }
3485            }
3486        }
3487        mProcessObservers.finishBroadcast();
3488    }
3489
3490    @Override
3491    public final int startActivity(IApplicationThread caller, String callingPackage,
3492            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3493            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3494        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3495            resultWho, requestCode, startFlags, profilerInfo, options,
3496            UserHandle.getCallingUserId());
3497    }
3498
3499    @Override
3500    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3501            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3502            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3503        enforceNotIsolatedCaller("startActivity");
3504        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3505                false, ALLOW_FULL_ONLY, "startActivity", null);
3506        // TODO: Switch to user app stacks here.
3507        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3508                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3509                profilerInfo, null, null, options, userId, null, null);
3510    }
3511
3512    @Override
3513    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3514            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3515            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3516
3517        // This is very dangerous -- it allows you to perform a start activity (including
3518        // permission grants) as any app that may launch one of your own activities.  So
3519        // we will only allow this to be done from activities that are part of the core framework,
3520        // and then only when they are running as the system.
3521        final ActivityRecord sourceRecord;
3522        final int targetUid;
3523        final String targetPackage;
3524        synchronized (this) {
3525            if (resultTo == null) {
3526                throw new SecurityException("Must be called from an activity");
3527            }
3528            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3529            if (sourceRecord == null) {
3530                throw new SecurityException("Called with bad activity token: " + resultTo);
3531            }
3532            if (!sourceRecord.info.packageName.equals("android")) {
3533                throw new SecurityException(
3534                        "Must be called from an activity that is declared in the android package");
3535            }
3536            if (sourceRecord.app == null) {
3537                throw new SecurityException("Called without a process attached to activity");
3538            }
3539            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3540                // This is still okay, as long as this activity is running under the
3541                // uid of the original calling activity.
3542                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3543                    throw new SecurityException(
3544                            "Calling activity in uid " + sourceRecord.app.uid
3545                                    + " must be system uid or original calling uid "
3546                                    + sourceRecord.launchedFromUid);
3547                }
3548            }
3549            targetUid = sourceRecord.launchedFromUid;
3550            targetPackage = sourceRecord.launchedFromPackage;
3551        }
3552
3553        // TODO: Switch to user app stacks here.
3554        try {
3555            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3556                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3557                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3558            return ret;
3559        } catch (SecurityException e) {
3560            // XXX need to figure out how to propagate to original app.
3561            // A SecurityException here is generally actually a fault of the original
3562            // calling activity (such as a fairly granting permissions), so propagate it
3563            // back to them.
3564            /*
3565            StringBuilder msg = new StringBuilder();
3566            msg.append("While launching");
3567            msg.append(intent.toString());
3568            msg.append(": ");
3569            msg.append(e.getMessage());
3570            */
3571            throw e;
3572        }
3573    }
3574
3575    @Override
3576    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3577            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3578            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3579        enforceNotIsolatedCaller("startActivityAndWait");
3580        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3581                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3582        WaitResult res = new WaitResult();
3583        // TODO: Switch to user app stacks here.
3584        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3585                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3586                options, userId, null, null);
3587        return res;
3588    }
3589
3590    @Override
3591    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3592            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3593            int startFlags, Configuration config, Bundle options, int userId) {
3594        enforceNotIsolatedCaller("startActivityWithConfig");
3595        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3596                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3597        // TODO: Switch to user app stacks here.
3598        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3599                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3600                null, null, config, options, userId, null, null);
3601        return ret;
3602    }
3603
3604    @Override
3605    public int startActivityIntentSender(IApplicationThread caller,
3606            IntentSender intent, Intent fillInIntent, String resolvedType,
3607            IBinder resultTo, String resultWho, int requestCode,
3608            int flagsMask, int flagsValues, Bundle options) {
3609        enforceNotIsolatedCaller("startActivityIntentSender");
3610        // Refuse possible leaked file descriptors
3611        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3612            throw new IllegalArgumentException("File descriptors passed in Intent");
3613        }
3614
3615        IIntentSender sender = intent.getTarget();
3616        if (!(sender instanceof PendingIntentRecord)) {
3617            throw new IllegalArgumentException("Bad PendingIntent object");
3618        }
3619
3620        PendingIntentRecord pir = (PendingIntentRecord)sender;
3621
3622        synchronized (this) {
3623            // If this is coming from the currently resumed activity, it is
3624            // effectively saying that app switches are allowed at this point.
3625            final ActivityStack stack = getFocusedStack();
3626            if (stack.mResumedActivity != null &&
3627                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3628                mAppSwitchesAllowedTime = 0;
3629            }
3630        }
3631        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3632                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3633        return ret;
3634    }
3635
3636    @Override
3637    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3638            Intent intent, String resolvedType, IVoiceInteractionSession session,
3639            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3640            Bundle options, int userId) {
3641        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3642                != PackageManager.PERMISSION_GRANTED) {
3643            String msg = "Permission Denial: startVoiceActivity() from pid="
3644                    + Binder.getCallingPid()
3645                    + ", uid=" + Binder.getCallingUid()
3646                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3647            Slog.w(TAG, msg);
3648            throw new SecurityException(msg);
3649        }
3650        if (session == null || interactor == null) {
3651            throw new NullPointerException("null session or interactor");
3652        }
3653        userId = handleIncomingUser(callingPid, callingUid, userId,
3654                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3655        // TODO: Switch to user app stacks here.
3656        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3657                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3658                null, options, userId, null, null);
3659    }
3660
3661    @Override
3662    public boolean startNextMatchingActivity(IBinder callingActivity,
3663            Intent intent, Bundle options) {
3664        // Refuse possible leaked file descriptors
3665        if (intent != null && intent.hasFileDescriptors() == true) {
3666            throw new IllegalArgumentException("File descriptors passed in Intent");
3667        }
3668
3669        synchronized (this) {
3670            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3671            if (r == null) {
3672                ActivityOptions.abort(options);
3673                return false;
3674            }
3675            if (r.app == null || r.app.thread == null) {
3676                // The caller is not running...  d'oh!
3677                ActivityOptions.abort(options);
3678                return false;
3679            }
3680            intent = new Intent(intent);
3681            // The caller is not allowed to change the data.
3682            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3683            // And we are resetting to find the next component...
3684            intent.setComponent(null);
3685
3686            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3687
3688            ActivityInfo aInfo = null;
3689            try {
3690                List<ResolveInfo> resolves =
3691                    AppGlobals.getPackageManager().queryIntentActivities(
3692                            intent, r.resolvedType,
3693                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3694                            UserHandle.getCallingUserId());
3695
3696                // Look for the original activity in the list...
3697                final int N = resolves != null ? resolves.size() : 0;
3698                for (int i=0; i<N; i++) {
3699                    ResolveInfo rInfo = resolves.get(i);
3700                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3701                            && rInfo.activityInfo.name.equals(r.info.name)) {
3702                        // We found the current one...  the next matching is
3703                        // after it.
3704                        i++;
3705                        if (i<N) {
3706                            aInfo = resolves.get(i).activityInfo;
3707                        }
3708                        if (debug) {
3709                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3710                                    + "/" + r.info.name);
3711                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3712                                    + "/" + aInfo.name);
3713                        }
3714                        break;
3715                    }
3716                }
3717            } catch (RemoteException e) {
3718            }
3719
3720            if (aInfo == null) {
3721                // Nobody who is next!
3722                ActivityOptions.abort(options);
3723                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3724                return false;
3725            }
3726
3727            intent.setComponent(new ComponentName(
3728                    aInfo.applicationInfo.packageName, aInfo.name));
3729            intent.setFlags(intent.getFlags()&~(
3730                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3731                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3732                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3733                    Intent.FLAG_ACTIVITY_NEW_TASK));
3734
3735            // Okay now we need to start the new activity, replacing the
3736            // currently running activity.  This is a little tricky because
3737            // we want to start the new one as if the current one is finished,
3738            // but not finish the current one first so that there is no flicker.
3739            // And thus...
3740            final boolean wasFinishing = r.finishing;
3741            r.finishing = true;
3742
3743            // Propagate reply information over to the new activity.
3744            final ActivityRecord resultTo = r.resultTo;
3745            final String resultWho = r.resultWho;
3746            final int requestCode = r.requestCode;
3747            r.resultTo = null;
3748            if (resultTo != null) {
3749                resultTo.removeResultsLocked(r, resultWho, requestCode);
3750            }
3751
3752            final long origId = Binder.clearCallingIdentity();
3753            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3754                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3755                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3756                    options, false, null, null, null);
3757            Binder.restoreCallingIdentity(origId);
3758
3759            r.finishing = wasFinishing;
3760            if (res != ActivityManager.START_SUCCESS) {
3761                return false;
3762            }
3763            return true;
3764        }
3765    }
3766
3767    @Override
3768    public final int startActivityFromRecents(int taskId, Bundle options) {
3769        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3770            String msg = "Permission Denial: startActivityFromRecents called without " +
3771                    START_TASKS_FROM_RECENTS;
3772            Slog.w(TAG, msg);
3773            throw new SecurityException(msg);
3774        }
3775        return startActivityFromRecentsInner(taskId, options);
3776    }
3777
3778    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3779        final TaskRecord task;
3780        final int callingUid;
3781        final String callingPackage;
3782        final Intent intent;
3783        final int userId;
3784        synchronized (this) {
3785            task = recentTaskForIdLocked(taskId);
3786            if (task == null) {
3787                throw new IllegalArgumentException("Task " + taskId + " not found.");
3788            }
3789            callingUid = task.mCallingUid;
3790            callingPackage = task.mCallingPackage;
3791            intent = task.intent;
3792            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3793            userId = task.userId;
3794        }
3795        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3796                options, userId, null, task);
3797    }
3798
3799    final int startActivityInPackage(int uid, String callingPackage,
3800            Intent intent, String resolvedType, IBinder resultTo,
3801            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3802            IActivityContainer container, TaskRecord inTask) {
3803
3804        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3805                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3806
3807        // TODO: Switch to user app stacks here.
3808        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3809                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3810                null, null, null, options, userId, container, inTask);
3811        return ret;
3812    }
3813
3814    @Override
3815    public final int startActivities(IApplicationThread caller, String callingPackage,
3816            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3817            int userId) {
3818        enforceNotIsolatedCaller("startActivities");
3819        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3820                false, ALLOW_FULL_ONLY, "startActivity", null);
3821        // TODO: Switch to user app stacks here.
3822        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3823                resolvedTypes, resultTo, options, userId);
3824        return ret;
3825    }
3826
3827    final int startActivitiesInPackage(int uid, String callingPackage,
3828            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3829            Bundle options, int userId) {
3830
3831        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3832                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3833        // TODO: Switch to user app stacks here.
3834        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3835                resultTo, options, userId);
3836        return ret;
3837    }
3838
3839    //explicitly remove thd old information in mRecentTasks when removing existing user.
3840    private void removeRecentTasksForUserLocked(int userId) {
3841        if(userId <= 0) {
3842            Slog.i(TAG, "Can't remove recent task on user " + userId);
3843            return;
3844        }
3845
3846        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3847            TaskRecord tr = mRecentTasks.get(i);
3848            if (tr.userId == userId) {
3849                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3850                        + " when finishing user" + userId);
3851                mRecentTasks.remove(i);
3852                tr.removedFromRecents(mTaskPersister);
3853            }
3854        }
3855
3856        // Remove tasks from persistent storage.
3857        mTaskPersister.wakeup(null, true);
3858    }
3859
3860    // Sort by taskId
3861    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3862        @Override
3863        public int compare(TaskRecord lhs, TaskRecord rhs) {
3864            return rhs.taskId - lhs.taskId;
3865        }
3866    };
3867
3868    // Extract the affiliates of the chain containing mRecentTasks[start].
3869    private int processNextAffiliateChain(int start) {
3870        final TaskRecord startTask = mRecentTasks.get(start);
3871        final int affiliateId = startTask.mAffiliatedTaskId;
3872
3873        // Quick identification of isolated tasks. I.e. those not launched behind.
3874        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3875                startTask.mNextAffiliate == null) {
3876            // There is still a slim chance that there are other tasks that point to this task
3877            // and that the chain is so messed up that this task no longer points to them but
3878            // the gain of this optimization outweighs the risk.
3879            startTask.inRecents = true;
3880            return start + 1;
3881        }
3882
3883        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3884        mTmpRecents.clear();
3885        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3886            final TaskRecord task = mRecentTasks.get(i);
3887            if (task.mAffiliatedTaskId == affiliateId) {
3888                mRecentTasks.remove(i);
3889                mTmpRecents.add(task);
3890            }
3891        }
3892
3893        // Sort them all by taskId. That is the order they were create in and that order will
3894        // always be correct.
3895        Collections.sort(mTmpRecents, mTaskRecordComparator);
3896
3897        // Go through and fix up the linked list.
3898        // The first one is the end of the chain and has no next.
3899        final TaskRecord first = mTmpRecents.get(0);
3900        first.inRecents = true;
3901        if (first.mNextAffiliate != null) {
3902            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3903            first.setNextAffiliate(null);
3904            mTaskPersister.wakeup(first, false);
3905        }
3906        // Everything in the middle is doubly linked from next to prev.
3907        final int tmpSize = mTmpRecents.size();
3908        for (int i = 0; i < tmpSize - 1; ++i) {
3909            final TaskRecord next = mTmpRecents.get(i);
3910            final TaskRecord prev = mTmpRecents.get(i + 1);
3911            if (next.mPrevAffiliate != prev) {
3912                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3913                        " setting prev=" + prev);
3914                next.setPrevAffiliate(prev);
3915                mTaskPersister.wakeup(next, false);
3916            }
3917            if (prev.mNextAffiliate != next) {
3918                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3919                        " setting next=" + next);
3920                prev.setNextAffiliate(next);
3921                mTaskPersister.wakeup(prev, false);
3922            }
3923            prev.inRecents = true;
3924        }
3925        // The last one is the beginning of the list and has no prev.
3926        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3927        if (last.mPrevAffiliate != null) {
3928            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3929            last.setPrevAffiliate(null);
3930            mTaskPersister.wakeup(last, false);
3931        }
3932
3933        // Insert the group back into mRecentTasks at start.
3934        mRecentTasks.addAll(start, mTmpRecents);
3935
3936        // Let the caller know where we left off.
3937        return start + tmpSize;
3938    }
3939
3940    /**
3941     * Update the recent tasks lists: make sure tasks should still be here (their
3942     * applications / activities still exist), update their availability, fixup ordering
3943     * of affiliations.
3944     */
3945    void cleanupRecentTasksLocked(int userId) {
3946        if (mRecentTasks == null) {
3947            // Happens when called from the packagemanager broadcast before boot.
3948            return;
3949        }
3950
3951        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3952        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3953        final IPackageManager pm = AppGlobals.getPackageManager();
3954        final ActivityInfo dummyAct = new ActivityInfo();
3955        final ApplicationInfo dummyApp = new ApplicationInfo();
3956
3957        int N = mRecentTasks.size();
3958
3959        int[] users = userId == UserHandle.USER_ALL
3960                ? getUsersLocked() : new int[] { userId };
3961        for (int user : users) {
3962            for (int i = 0; i < N; i++) {
3963                TaskRecord task = mRecentTasks.get(i);
3964                if (task.userId != user) {
3965                    // Only look at tasks for the user ID of interest.
3966                    continue;
3967                }
3968                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3969                    // This situation is broken, and we should just get rid of it now.
3970                    mRecentTasks.remove(i);
3971                    task.removedFromRecents(mTaskPersister);
3972                    i--;
3973                    N--;
3974                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3975                    continue;
3976                }
3977                // Check whether this activity is currently available.
3978                if (task.realActivity != null) {
3979                    ActivityInfo ai = availActCache.get(task.realActivity);
3980                    if (ai == null) {
3981                        try {
3982                            ai = pm.getActivityInfo(task.realActivity,
3983                                    PackageManager.GET_UNINSTALLED_PACKAGES
3984                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3985                        } catch (RemoteException e) {
3986                            // Will never happen.
3987                            continue;
3988                        }
3989                        if (ai == null) {
3990                            ai = dummyAct;
3991                        }
3992                        availActCache.put(task.realActivity, ai);
3993                    }
3994                    if (ai == dummyAct) {
3995                        // This could be either because the activity no longer exists, or the
3996                        // app is temporarily gone.  For the former we want to remove the recents
3997                        // entry; for the latter we want to mark it as unavailable.
3998                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3999                        if (app == null) {
4000                            try {
4001                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4002                                        PackageManager.GET_UNINSTALLED_PACKAGES
4003                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4004                            } catch (RemoteException e) {
4005                                // Will never happen.
4006                                continue;
4007                            }
4008                            if (app == null) {
4009                                app = dummyApp;
4010                            }
4011                            availAppCache.put(task.realActivity.getPackageName(), app);
4012                        }
4013                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4014                            // Doesn't exist any more!  Good-bye.
4015                            mRecentTasks.remove(i);
4016                            task.removedFromRecents(mTaskPersister);
4017                            i--;
4018                            N--;
4019                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4020                            continue;
4021                        } else {
4022                            // Otherwise just not available for now.
4023                            if (task.isAvailable) {
4024                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4025                                        + task);
4026                            }
4027                            task.isAvailable = false;
4028                        }
4029                    } else {
4030                        if (!ai.enabled || !ai.applicationInfo.enabled
4031                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4032                            if (task.isAvailable) {
4033                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4034                                        + task + " (enabled=" + ai.enabled + "/"
4035                                        + ai.applicationInfo.enabled +  " flags="
4036                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4037                            }
4038                            task.isAvailable = false;
4039                        } else {
4040                            if (!task.isAvailable) {
4041                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4042                                        + task);
4043                            }
4044                            task.isAvailable = true;
4045                        }
4046                    }
4047                }
4048            }
4049        }
4050
4051        // Verify the affiliate chain for each task.
4052        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4053        }
4054
4055        mTmpRecents.clear();
4056        // mRecentTasks is now in sorted, affiliated order.
4057    }
4058
4059    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4060        int N = mRecentTasks.size();
4061        TaskRecord top = task;
4062        int topIndex = taskIndex;
4063        while (top.mNextAffiliate != null && topIndex > 0) {
4064            top = top.mNextAffiliate;
4065            topIndex--;
4066        }
4067        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4068                + topIndex + " from intial " + taskIndex);
4069        // Find the end of the chain, doing a sanity check along the way.
4070        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4071        int endIndex = topIndex;
4072        TaskRecord prev = top;
4073        while (endIndex < N) {
4074            TaskRecord cur = mRecentTasks.get(endIndex);
4075            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4076                    + endIndex + " " + cur);
4077            if (cur == top) {
4078                // Verify start of the chain.
4079                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4080                    Slog.wtf(TAG, "Bad chain @" + endIndex
4081                            + ": first task has next affiliate: " + prev);
4082                    sane = false;
4083                    break;
4084                }
4085            } else {
4086                // Verify middle of the chain's next points back to the one before.
4087                if (cur.mNextAffiliate != prev
4088                        || cur.mNextAffiliateTaskId != prev.taskId) {
4089                    Slog.wtf(TAG, "Bad chain @" + endIndex
4090                            + ": middle task " + cur + " @" + endIndex
4091                            + " has bad next affiliate "
4092                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4093                            + ", expected " + prev);
4094                    sane = false;
4095                    break;
4096                }
4097            }
4098            if (cur.mPrevAffiliateTaskId == -1) {
4099                // Chain ends here.
4100                if (cur.mPrevAffiliate != null) {
4101                    Slog.wtf(TAG, "Bad chain @" + endIndex
4102                            + ": last task " + cur + " has previous affiliate "
4103                            + cur.mPrevAffiliate);
4104                    sane = false;
4105                }
4106                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4107                break;
4108            } else {
4109                // Verify middle of the chain's prev points to a valid item.
4110                if (cur.mPrevAffiliate == null) {
4111                    Slog.wtf(TAG, "Bad chain @" + endIndex
4112                            + ": task " + cur + " has previous affiliate "
4113                            + cur.mPrevAffiliate + " but should be id "
4114                            + cur.mPrevAffiliate);
4115                    sane = false;
4116                    break;
4117                }
4118            }
4119            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4120                Slog.wtf(TAG, "Bad chain @" + endIndex
4121                        + ": task " + cur + " has affiliated id "
4122                        + cur.mAffiliatedTaskId + " but should be "
4123                        + task.mAffiliatedTaskId);
4124                sane = false;
4125                break;
4126            }
4127            prev = cur;
4128            endIndex++;
4129            if (endIndex >= N) {
4130                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4131                        + ": last task " + prev);
4132                sane = false;
4133                break;
4134            }
4135        }
4136        if (sane) {
4137            if (endIndex < taskIndex) {
4138                Slog.wtf(TAG, "Bad chain @" + endIndex
4139                        + ": did not extend to task " + task + " @" + taskIndex);
4140                sane = false;
4141            }
4142        }
4143        if (sane) {
4144            // All looks good, we can just move all of the affiliated tasks
4145            // to the top.
4146            for (int i=topIndex; i<=endIndex; i++) {
4147                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4148                        + " from " + i + " to " + (i-topIndex));
4149                TaskRecord cur = mRecentTasks.remove(i);
4150                mRecentTasks.add(i-topIndex, cur);
4151            }
4152            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4153                    + " to " + endIndex);
4154            return true;
4155        }
4156
4157        // Whoops, couldn't do it.
4158        return false;
4159    }
4160
4161    final void addRecentTaskLocked(TaskRecord task) {
4162        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4163                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4164
4165        int N = mRecentTasks.size();
4166        // Quick case: check if the top-most recent task is the same.
4167        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4168            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4169            return;
4170        }
4171        // Another quick case: check if this is part of a set of affiliated
4172        // tasks that are at the top.
4173        if (isAffiliated && N > 0 && task.inRecents
4174                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4175            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4176                    + " at top when adding " + task);
4177            return;
4178        }
4179        // Another quick case: never add voice sessions.
4180        if (task.voiceSession != null) {
4181            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4182            return;
4183        }
4184
4185        boolean needAffiliationFix = false;
4186
4187        // Slightly less quick case: the task is already in recents, so all we need
4188        // to do is move it.
4189        if (task.inRecents) {
4190            int taskIndex = mRecentTasks.indexOf(task);
4191            if (taskIndex >= 0) {
4192                if (!isAffiliated) {
4193                    // Simple case: this is not an affiliated task, so we just move it to the front.
4194                    mRecentTasks.remove(taskIndex);
4195                    mRecentTasks.add(0, task);
4196                    notifyTaskPersisterLocked(task, false);
4197                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4198                            + " from " + taskIndex);
4199                    return;
4200                } else {
4201                    // More complicated: need to keep all affiliated tasks together.
4202                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4203                        // All went well.
4204                        return;
4205                    }
4206
4207                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4208                    // everything and then go through our general path of adding a new task.
4209                    needAffiliationFix = true;
4210                }
4211            } else {
4212                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4213                needAffiliationFix = true;
4214            }
4215        }
4216
4217        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4218        trimRecentsForTask(task, true);
4219
4220        N = mRecentTasks.size();
4221        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4222            final TaskRecord tr = mRecentTasks.remove(N - 1);
4223            tr.removedFromRecents(mTaskPersister);
4224            N--;
4225        }
4226        task.inRecents = true;
4227        if (!isAffiliated || needAffiliationFix) {
4228            // If this is a simple non-affiliated task, or we had some failure trying to
4229            // handle it as part of an affilated task, then just place it at the top.
4230            mRecentTasks.add(0, task);
4231        } else if (isAffiliated) {
4232            // If this is a new affiliated task, then move all of the affiliated tasks
4233            // to the front and insert this new one.
4234            TaskRecord other = task.mNextAffiliate;
4235            if (other == null) {
4236                other = task.mPrevAffiliate;
4237            }
4238            if (other != null) {
4239                int otherIndex = mRecentTasks.indexOf(other);
4240                if (otherIndex >= 0) {
4241                    // Insert new task at appropriate location.
4242                    int taskIndex;
4243                    if (other == task.mNextAffiliate) {
4244                        // We found the index of our next affiliation, which is who is
4245                        // before us in the list, so add after that point.
4246                        taskIndex = otherIndex+1;
4247                    } else {
4248                        // We found the index of our previous affiliation, which is who is
4249                        // after us in the list, so add at their position.
4250                        taskIndex = otherIndex;
4251                    }
4252                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4253                            + taskIndex + ": " + task);
4254                    mRecentTasks.add(taskIndex, task);
4255
4256                    // Now move everything to the front.
4257                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4258                        // All went well.
4259                        return;
4260                    }
4261
4262                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4263                    // everything and then go through our general path of adding a new task.
4264                    needAffiliationFix = true;
4265                } else {
4266                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4267                            + other);
4268                    needAffiliationFix = true;
4269                }
4270            } else {
4271                if (DEBUG_RECENTS) Slog.d(TAG,
4272                        "addRecent: adding affiliated task without next/prev:" + task);
4273                needAffiliationFix = true;
4274            }
4275        }
4276        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4277
4278        if (needAffiliationFix) {
4279            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4280            cleanupRecentTasksLocked(task.userId);
4281        }
4282    }
4283
4284    /**
4285     * If needed, remove oldest existing entries in recents that are for the same kind
4286     * of task as the given one.
4287     */
4288    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4289        int N = mRecentTasks.size();
4290        final Intent intent = task.intent;
4291        final boolean document = intent != null && intent.isDocument();
4292
4293        int maxRecents = task.maxRecents - 1;
4294        for (int i=0; i<N; i++) {
4295            final TaskRecord tr = mRecentTasks.get(i);
4296            if (task != tr) {
4297                if (task.userId != tr.userId) {
4298                    continue;
4299                }
4300                if (i > MAX_RECENT_BITMAPS) {
4301                    tr.freeLastThumbnail();
4302                }
4303                final Intent trIntent = tr.intent;
4304                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4305                    (intent == null || !intent.filterEquals(trIntent))) {
4306                    continue;
4307                }
4308                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4309                if (document && trIsDocument) {
4310                    // These are the same document activity (not necessarily the same doc).
4311                    if (maxRecents > 0) {
4312                        --maxRecents;
4313                        continue;
4314                    }
4315                    // Hit the maximum number of documents for this task. Fall through
4316                    // and remove this document from recents.
4317                } else if (document || trIsDocument) {
4318                    // Only one of these is a document. Not the droid we're looking for.
4319                    continue;
4320                }
4321            }
4322
4323            if (!doTrim) {
4324                // If the caller is not actually asking for a trim, just tell them we reached
4325                // a point where the trim would happen.
4326                return i;
4327            }
4328
4329            // Either task and tr are the same or, their affinities match or their intents match
4330            // and neither of them is a document, or they are documents using the same activity
4331            // and their maxRecents has been reached.
4332            tr.disposeThumbnail();
4333            mRecentTasks.remove(i);
4334            if (task != tr) {
4335                tr.removedFromRecents(mTaskPersister);
4336            }
4337            i--;
4338            N--;
4339            if (task.intent == null) {
4340                // If the new recent task we are adding is not fully
4341                // specified, then replace it with the existing recent task.
4342                task = tr;
4343            }
4344            notifyTaskPersisterLocked(tr, false);
4345        }
4346
4347        return -1;
4348    }
4349
4350    @Override
4351    public void reportActivityFullyDrawn(IBinder token) {
4352        synchronized (this) {
4353            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4354            if (r == null) {
4355                return;
4356            }
4357            r.reportFullyDrawnLocked();
4358        }
4359    }
4360
4361    @Override
4362    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4363        synchronized (this) {
4364            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4365            if (r == null) {
4366                return;
4367            }
4368            final long origId = Binder.clearCallingIdentity();
4369            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4370            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4371                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4372            if (config != null) {
4373                r.frozenBeforeDestroy = true;
4374                if (!updateConfigurationLocked(config, r, false, false)) {
4375                    mStackSupervisor.resumeTopActivitiesLocked();
4376                }
4377            }
4378            Binder.restoreCallingIdentity(origId);
4379        }
4380    }
4381
4382    @Override
4383    public int getRequestedOrientation(IBinder token) {
4384        synchronized (this) {
4385            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4386            if (r == null) {
4387                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4388            }
4389            return mWindowManager.getAppOrientation(r.appToken);
4390        }
4391    }
4392
4393    /**
4394     * This is the internal entry point for handling Activity.finish().
4395     *
4396     * @param token The Binder token referencing the Activity we want to finish.
4397     * @param resultCode Result code, if any, from this Activity.
4398     * @param resultData Result data (Intent), if any, from this Activity.
4399     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4400     *            the root Activity in the task.
4401     *
4402     * @return Returns true if the activity successfully finished, or false if it is still running.
4403     */
4404    @Override
4405    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4406            boolean finishTask) {
4407        // Refuse possible leaked file descriptors
4408        if (resultData != null && resultData.hasFileDescriptors() == true) {
4409            throw new IllegalArgumentException("File descriptors passed in Intent");
4410        }
4411
4412        synchronized(this) {
4413            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4414            if (r == null) {
4415                return true;
4416            }
4417            // Keep track of the root activity of the task before we finish it
4418            TaskRecord tr = r.task;
4419            ActivityRecord rootR = tr.getRootActivity();
4420            // Do not allow task to finish in Lock Task mode.
4421            if (tr == mStackSupervisor.mLockTaskModeTask) {
4422                if (rootR == r) {
4423                    mStackSupervisor.showLockTaskToast();
4424                    return false;
4425                }
4426            }
4427            if (mController != null) {
4428                // Find the first activity that is not finishing.
4429                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4430                if (next != null) {
4431                    // ask watcher if this is allowed
4432                    boolean resumeOK = true;
4433                    try {
4434                        resumeOK = mController.activityResuming(next.packageName);
4435                    } catch (RemoteException e) {
4436                        mController = null;
4437                        Watchdog.getInstance().setActivityController(null);
4438                    }
4439
4440                    if (!resumeOK) {
4441                        return false;
4442                    }
4443                }
4444            }
4445            final long origId = Binder.clearCallingIdentity();
4446            try {
4447                boolean res;
4448                if (finishTask && r == rootR) {
4449                    // If requested, remove the task that is associated to this activity only if it
4450                    // was the root activity in the task.  The result code and data is ignored because
4451                    // we don't support returning them across task boundaries.
4452                    res = removeTaskByIdLocked(tr.taskId, 0);
4453                } else {
4454                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4455                            resultData, "app-request", true);
4456                }
4457                return res;
4458            } finally {
4459                Binder.restoreCallingIdentity(origId);
4460            }
4461        }
4462    }
4463
4464    @Override
4465    public final void finishHeavyWeightApp() {
4466        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4467                != PackageManager.PERMISSION_GRANTED) {
4468            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4469                    + Binder.getCallingPid()
4470                    + ", uid=" + Binder.getCallingUid()
4471                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4472            Slog.w(TAG, msg);
4473            throw new SecurityException(msg);
4474        }
4475
4476        synchronized(this) {
4477            if (mHeavyWeightProcess == null) {
4478                return;
4479            }
4480
4481            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4482                    mHeavyWeightProcess.activities);
4483            for (int i=0; i<activities.size(); i++) {
4484                ActivityRecord r = activities.get(i);
4485                if (!r.finishing) {
4486                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4487                            null, "finish-heavy", true);
4488                }
4489            }
4490
4491            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4492                    mHeavyWeightProcess.userId, 0));
4493            mHeavyWeightProcess = null;
4494        }
4495    }
4496
4497    @Override
4498    public void crashApplication(int uid, int initialPid, String packageName,
4499            String message) {
4500        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4501                != PackageManager.PERMISSION_GRANTED) {
4502            String msg = "Permission Denial: crashApplication() from pid="
4503                    + Binder.getCallingPid()
4504                    + ", uid=" + Binder.getCallingUid()
4505                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4506            Slog.w(TAG, msg);
4507            throw new SecurityException(msg);
4508        }
4509
4510        synchronized(this) {
4511            ProcessRecord proc = null;
4512
4513            // Figure out which process to kill.  We don't trust that initialPid
4514            // still has any relation to current pids, so must scan through the
4515            // list.
4516            synchronized (mPidsSelfLocked) {
4517                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4518                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4519                    if (p.uid != uid) {
4520                        continue;
4521                    }
4522                    if (p.pid == initialPid) {
4523                        proc = p;
4524                        break;
4525                    }
4526                    if (p.pkgList.containsKey(packageName)) {
4527                        proc = p;
4528                    }
4529                }
4530            }
4531
4532            if (proc == null) {
4533                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4534                        + " initialPid=" + initialPid
4535                        + " packageName=" + packageName);
4536                return;
4537            }
4538
4539            if (proc.thread != null) {
4540                if (proc.pid == Process.myPid()) {
4541                    Log.w(TAG, "crashApplication: trying to crash self!");
4542                    return;
4543                }
4544                long ident = Binder.clearCallingIdentity();
4545                try {
4546                    proc.thread.scheduleCrash(message);
4547                } catch (RemoteException e) {
4548                }
4549                Binder.restoreCallingIdentity(ident);
4550            }
4551        }
4552    }
4553
4554    @Override
4555    public final void finishSubActivity(IBinder token, String resultWho,
4556            int requestCode) {
4557        synchronized(this) {
4558            final long origId = Binder.clearCallingIdentity();
4559            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4560            if (r != null) {
4561                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4562            }
4563            Binder.restoreCallingIdentity(origId);
4564        }
4565    }
4566
4567    @Override
4568    public boolean finishActivityAffinity(IBinder token) {
4569        synchronized(this) {
4570            final long origId = Binder.clearCallingIdentity();
4571            try {
4572                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4573
4574                ActivityRecord rootR = r.task.getRootActivity();
4575                // Do not allow task to finish in Lock Task mode.
4576                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4577                    if (rootR == r) {
4578                        mStackSupervisor.showLockTaskToast();
4579                        return false;
4580                    }
4581                }
4582                boolean res = false;
4583                if (r != null) {
4584                    res = r.task.stack.finishActivityAffinityLocked(r);
4585                }
4586                return res;
4587            } finally {
4588                Binder.restoreCallingIdentity(origId);
4589            }
4590        }
4591    }
4592
4593    @Override
4594    public void finishVoiceTask(IVoiceInteractionSession session) {
4595        synchronized(this) {
4596            final long origId = Binder.clearCallingIdentity();
4597            try {
4598                mStackSupervisor.finishVoiceTask(session);
4599            } finally {
4600                Binder.restoreCallingIdentity(origId);
4601            }
4602        }
4603
4604    }
4605
4606    @Override
4607    public boolean releaseActivityInstance(IBinder token) {
4608        synchronized(this) {
4609            final long origId = Binder.clearCallingIdentity();
4610            try {
4611                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4612                if (r.task == null || r.task.stack == null) {
4613                    return false;
4614                }
4615                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4616            } finally {
4617                Binder.restoreCallingIdentity(origId);
4618            }
4619        }
4620    }
4621
4622    @Override
4623    public void releaseSomeActivities(IApplicationThread appInt) {
4624        synchronized(this) {
4625            final long origId = Binder.clearCallingIdentity();
4626            try {
4627                ProcessRecord app = getRecordForAppLocked(appInt);
4628                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4629            } finally {
4630                Binder.restoreCallingIdentity(origId);
4631            }
4632        }
4633    }
4634
4635    @Override
4636    public boolean willActivityBeVisible(IBinder token) {
4637        synchronized(this) {
4638            ActivityStack stack = ActivityRecord.getStackLocked(token);
4639            if (stack != null) {
4640                return stack.willActivityBeVisibleLocked(token);
4641            }
4642            return false;
4643        }
4644    }
4645
4646    @Override
4647    public void overridePendingTransition(IBinder token, String packageName,
4648            int enterAnim, int exitAnim) {
4649        synchronized(this) {
4650            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4651            if (self == null) {
4652                return;
4653            }
4654
4655            final long origId = Binder.clearCallingIdentity();
4656
4657            if (self.state == ActivityState.RESUMED
4658                    || self.state == ActivityState.PAUSING) {
4659                mWindowManager.overridePendingAppTransition(packageName,
4660                        enterAnim, exitAnim, null);
4661            }
4662
4663            Binder.restoreCallingIdentity(origId);
4664        }
4665    }
4666
4667    /**
4668     * Main function for removing an existing process from the activity manager
4669     * as a result of that process going away.  Clears out all connections
4670     * to the process.
4671     */
4672    private final void handleAppDiedLocked(ProcessRecord app,
4673            boolean restarting, boolean allowRestart) {
4674        int pid = app.pid;
4675        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4676        if (!restarting) {
4677            removeLruProcessLocked(app);
4678            if (pid > 0) {
4679                ProcessList.remove(pid);
4680            }
4681        }
4682
4683        if (mProfileProc == app) {
4684            clearProfilerLocked();
4685        }
4686
4687        // Remove this application's activities from active lists.
4688        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4689
4690        app.activities.clear();
4691
4692        if (app.instrumentationClass != null) {
4693            Slog.w(TAG, "Crash of app " + app.processName
4694                  + " running instrumentation " + app.instrumentationClass);
4695            Bundle info = new Bundle();
4696            info.putString("shortMsg", "Process crashed.");
4697            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4698        }
4699
4700        if (!restarting) {
4701            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4702                // If there was nothing to resume, and we are not already
4703                // restarting this process, but there is a visible activity that
4704                // is hosted by the process...  then make sure all visible
4705                // activities are running, taking care of restarting this
4706                // process.
4707                if (hasVisibleActivities) {
4708                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4709                }
4710            }
4711        }
4712    }
4713
4714    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4715        IBinder threadBinder = thread.asBinder();
4716        // Find the application record.
4717        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4718            ProcessRecord rec = mLruProcesses.get(i);
4719            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4720                return i;
4721            }
4722        }
4723        return -1;
4724    }
4725
4726    final ProcessRecord getRecordForAppLocked(
4727            IApplicationThread thread) {
4728        if (thread == null) {
4729            return null;
4730        }
4731
4732        int appIndex = getLRURecordIndexForAppLocked(thread);
4733        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4734    }
4735
4736    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4737        // If there are no longer any background processes running,
4738        // and the app that died was not running instrumentation,
4739        // then tell everyone we are now low on memory.
4740        boolean haveBg = false;
4741        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4742            ProcessRecord rec = mLruProcesses.get(i);
4743            if (rec.thread != null
4744                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4745                haveBg = true;
4746                break;
4747            }
4748        }
4749
4750        if (!haveBg) {
4751            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4752            if (doReport) {
4753                long now = SystemClock.uptimeMillis();
4754                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4755                    doReport = false;
4756                } else {
4757                    mLastMemUsageReportTime = now;
4758                }
4759            }
4760            final ArrayList<ProcessMemInfo> memInfos
4761                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4762            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4763            long now = SystemClock.uptimeMillis();
4764            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4765                ProcessRecord rec = mLruProcesses.get(i);
4766                if (rec == dyingProc || rec.thread == null) {
4767                    continue;
4768                }
4769                if (doReport) {
4770                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4771                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4772                }
4773                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4774                    // The low memory report is overriding any current
4775                    // state for a GC request.  Make sure to do
4776                    // heavy/important/visible/foreground processes first.
4777                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4778                        rec.lastRequestedGc = 0;
4779                    } else {
4780                        rec.lastRequestedGc = rec.lastLowMemory;
4781                    }
4782                    rec.reportLowMemory = true;
4783                    rec.lastLowMemory = now;
4784                    mProcessesToGc.remove(rec);
4785                    addProcessToGcListLocked(rec);
4786                }
4787            }
4788            if (doReport) {
4789                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4790                mHandler.sendMessage(msg);
4791            }
4792            scheduleAppGcsLocked();
4793        }
4794    }
4795
4796    final void appDiedLocked(ProcessRecord app) {
4797       appDiedLocked(app, app.pid, app.thread);
4798    }
4799
4800    final void appDiedLocked(ProcessRecord app, int pid,
4801            IApplicationThread thread) {
4802
4803        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4804        synchronized (stats) {
4805            stats.noteProcessDiedLocked(app.info.uid, pid);
4806        }
4807
4808        Process.killProcessGroup(app.info.uid, pid);
4809
4810        // Clean up already done if the process has been re-started.
4811        if (app.pid == pid && app.thread != null &&
4812                app.thread.asBinder() == thread.asBinder()) {
4813            boolean doLowMem = app.instrumentationClass == null;
4814            boolean doOomAdj = doLowMem;
4815            if (!app.killedByAm) {
4816                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4817                        + ") has died.");
4818                mAllowLowerMemLevel = true;
4819            } else {
4820                // Note that we always want to do oom adj to update our state with the
4821                // new number of procs.
4822                mAllowLowerMemLevel = false;
4823                doLowMem = false;
4824            }
4825            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4826            if (DEBUG_CLEANUP) Slog.v(
4827                TAG, "Dying app: " + app + ", pid: " + pid
4828                + ", thread: " + thread.asBinder());
4829            handleAppDiedLocked(app, false, true);
4830
4831            if (doOomAdj) {
4832                updateOomAdjLocked();
4833            }
4834            if (doLowMem) {
4835                doLowMemReportIfNeededLocked(app);
4836            }
4837        } else if (app.pid != pid) {
4838            // A new process has already been started.
4839            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4840                    + ") has died and restarted (pid " + app.pid + ").");
4841            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4842        } else if (DEBUG_PROCESSES) {
4843            Slog.d(TAG, "Received spurious death notification for thread "
4844                    + thread.asBinder());
4845        }
4846    }
4847
4848    /**
4849     * If a stack trace dump file is configured, dump process stack traces.
4850     * @param clearTraces causes the dump file to be erased prior to the new
4851     *    traces being written, if true; when false, the new traces will be
4852     *    appended to any existing file content.
4853     * @param firstPids of dalvik VM processes to dump stack traces for first
4854     * @param lastPids of dalvik VM processes to dump stack traces for last
4855     * @param nativeProcs optional list of native process names to dump stack crawls
4856     * @return file containing stack traces, or null if no dump file is configured
4857     */
4858    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4859            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4860        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4861        if (tracesPath == null || tracesPath.length() == 0) {
4862            return null;
4863        }
4864
4865        File tracesFile = new File(tracesPath);
4866        try {
4867            File tracesDir = tracesFile.getParentFile();
4868            if (!tracesDir.exists()) {
4869                tracesFile.mkdirs();
4870                if (!SELinux.restorecon(tracesDir)) {
4871                    return null;
4872                }
4873            }
4874            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4875
4876            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4877            tracesFile.createNewFile();
4878            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4879        } catch (IOException e) {
4880            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4881            return null;
4882        }
4883
4884        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4885        return tracesFile;
4886    }
4887
4888    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4889            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4890        // Use a FileObserver to detect when traces finish writing.
4891        // The order of traces is considered important to maintain for legibility.
4892        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4893            @Override
4894            public synchronized void onEvent(int event, String path) { notify(); }
4895        };
4896
4897        try {
4898            observer.startWatching();
4899
4900            // First collect all of the stacks of the most important pids.
4901            if (firstPids != null) {
4902                try {
4903                    int num = firstPids.size();
4904                    for (int i = 0; i < num; i++) {
4905                        synchronized (observer) {
4906                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4907                            observer.wait(200);  // Wait for write-close, give up after 200msec
4908                        }
4909                    }
4910                } catch (InterruptedException e) {
4911                    Log.wtf(TAG, e);
4912                }
4913            }
4914
4915            // Next collect the stacks of the native pids
4916            if (nativeProcs != null) {
4917                int[] pids = Process.getPidsForCommands(nativeProcs);
4918                if (pids != null) {
4919                    for (int pid : pids) {
4920                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4921                    }
4922                }
4923            }
4924
4925            // Lastly, measure CPU usage.
4926            if (processCpuTracker != null) {
4927                processCpuTracker.init();
4928                System.gc();
4929                processCpuTracker.update();
4930                try {
4931                    synchronized (processCpuTracker) {
4932                        processCpuTracker.wait(500); // measure over 1/2 second.
4933                    }
4934                } catch (InterruptedException e) {
4935                }
4936                processCpuTracker.update();
4937
4938                // We'll take the stack crawls of just the top apps using CPU.
4939                final int N = processCpuTracker.countWorkingStats();
4940                int numProcs = 0;
4941                for (int i=0; i<N && numProcs<5; i++) {
4942                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4943                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4944                        numProcs++;
4945                        try {
4946                            synchronized (observer) {
4947                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4948                                observer.wait(200);  // Wait for write-close, give up after 200msec
4949                            }
4950                        } catch (InterruptedException e) {
4951                            Log.wtf(TAG, e);
4952                        }
4953
4954                    }
4955                }
4956            }
4957        } finally {
4958            observer.stopWatching();
4959        }
4960    }
4961
4962    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4963        if (true || IS_USER_BUILD) {
4964            return;
4965        }
4966        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4967        if (tracesPath == null || tracesPath.length() == 0) {
4968            return;
4969        }
4970
4971        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4972        StrictMode.allowThreadDiskWrites();
4973        try {
4974            final File tracesFile = new File(tracesPath);
4975            final File tracesDir = tracesFile.getParentFile();
4976            final File tracesTmp = new File(tracesDir, "__tmp__");
4977            try {
4978                if (!tracesDir.exists()) {
4979                    tracesFile.mkdirs();
4980                    if (!SELinux.restorecon(tracesDir.getPath())) {
4981                        return;
4982                    }
4983                }
4984                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4985
4986                if (tracesFile.exists()) {
4987                    tracesTmp.delete();
4988                    tracesFile.renameTo(tracesTmp);
4989                }
4990                StringBuilder sb = new StringBuilder();
4991                Time tobj = new Time();
4992                tobj.set(System.currentTimeMillis());
4993                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4994                sb.append(": ");
4995                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4996                sb.append(" since ");
4997                sb.append(msg);
4998                FileOutputStream fos = new FileOutputStream(tracesFile);
4999                fos.write(sb.toString().getBytes());
5000                if (app == null) {
5001                    fos.write("\n*** No application process!".getBytes());
5002                }
5003                fos.close();
5004                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5005            } catch (IOException e) {
5006                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5007                return;
5008            }
5009
5010            if (app != null) {
5011                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5012                firstPids.add(app.pid);
5013                dumpStackTraces(tracesPath, firstPids, null, null, null);
5014            }
5015
5016            File lastTracesFile = null;
5017            File curTracesFile = null;
5018            for (int i=9; i>=0; i--) {
5019                String name = String.format(Locale.US, "slow%02d.txt", i);
5020                curTracesFile = new File(tracesDir, name);
5021                if (curTracesFile.exists()) {
5022                    if (lastTracesFile != null) {
5023                        curTracesFile.renameTo(lastTracesFile);
5024                    } else {
5025                        curTracesFile.delete();
5026                    }
5027                }
5028                lastTracesFile = curTracesFile;
5029            }
5030            tracesFile.renameTo(curTracesFile);
5031            if (tracesTmp.exists()) {
5032                tracesTmp.renameTo(tracesFile);
5033            }
5034        } finally {
5035            StrictMode.setThreadPolicy(oldPolicy);
5036        }
5037    }
5038
5039    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5040            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5041        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5042        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5043
5044        if (mController != null) {
5045            try {
5046                // 0 == continue, -1 = kill process immediately
5047                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5048                if (res < 0 && app.pid != MY_PID) {
5049                    app.kill("anr", true);
5050                }
5051            } catch (RemoteException e) {
5052                mController = null;
5053                Watchdog.getInstance().setActivityController(null);
5054            }
5055        }
5056
5057        long anrTime = SystemClock.uptimeMillis();
5058        if (MONITOR_CPU_USAGE) {
5059            updateCpuStatsNow();
5060        }
5061
5062        synchronized (this) {
5063            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5064            if (mShuttingDown) {
5065                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5066                return;
5067            } else if (app.notResponding) {
5068                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5069                return;
5070            } else if (app.crashing) {
5071                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5072                return;
5073            }
5074
5075            // In case we come through here for the same app before completing
5076            // this one, mark as anring now so we will bail out.
5077            app.notResponding = true;
5078
5079            // Log the ANR to the event log.
5080            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5081                    app.processName, app.info.flags, annotation);
5082
5083            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5084            firstPids.add(app.pid);
5085
5086            int parentPid = app.pid;
5087            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5088            if (parentPid != app.pid) firstPids.add(parentPid);
5089
5090            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5091
5092            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5093                ProcessRecord r = mLruProcesses.get(i);
5094                if (r != null && r.thread != null) {
5095                    int pid = r.pid;
5096                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5097                        if (r.persistent) {
5098                            firstPids.add(pid);
5099                        } else {
5100                            lastPids.put(pid, Boolean.TRUE);
5101                        }
5102                    }
5103                }
5104            }
5105        }
5106
5107        // Log the ANR to the main log.
5108        StringBuilder info = new StringBuilder();
5109        info.setLength(0);
5110        info.append("ANR in ").append(app.processName);
5111        if (activity != null && activity.shortComponentName != null) {
5112            info.append(" (").append(activity.shortComponentName).append(")");
5113        }
5114        info.append("\n");
5115        info.append("PID: ").append(app.pid).append("\n");
5116        if (annotation != null) {
5117            info.append("Reason: ").append(annotation).append("\n");
5118        }
5119        if (parent != null && parent != activity) {
5120            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5121        }
5122
5123        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5124
5125        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5126                NATIVE_STACKS_OF_INTEREST);
5127
5128        String cpuInfo = null;
5129        if (MONITOR_CPU_USAGE) {
5130            updateCpuStatsNow();
5131            synchronized (mProcessCpuTracker) {
5132                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5133            }
5134            info.append(processCpuTracker.printCurrentLoad());
5135            info.append(cpuInfo);
5136        }
5137
5138        info.append(processCpuTracker.printCurrentState(anrTime));
5139
5140        Slog.e(TAG, info.toString());
5141        if (tracesFile == null) {
5142            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5143            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5144        }
5145
5146        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5147                cpuInfo, tracesFile, null);
5148
5149        if (mController != null) {
5150            try {
5151                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5152                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5153                if (res != 0) {
5154                    if (res < 0 && app.pid != MY_PID) {
5155                        app.kill("anr", true);
5156                    } else {
5157                        synchronized (this) {
5158                            mServices.scheduleServiceTimeoutLocked(app);
5159                        }
5160                    }
5161                    return;
5162                }
5163            } catch (RemoteException e) {
5164                mController = null;
5165                Watchdog.getInstance().setActivityController(null);
5166            }
5167        }
5168
5169        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5170        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5171                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5172
5173        synchronized (this) {
5174            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5175                app.kill("bg anr", true);
5176                return;
5177            }
5178
5179            // Set the app's notResponding state, and look up the errorReportReceiver
5180            makeAppNotRespondingLocked(app,
5181                    activity != null ? activity.shortComponentName : null,
5182                    annotation != null ? "ANR " + annotation : "ANR",
5183                    info.toString());
5184
5185            // Bring up the infamous App Not Responding dialog
5186            Message msg = Message.obtain();
5187            HashMap<String, Object> map = new HashMap<String, Object>();
5188            msg.what = SHOW_NOT_RESPONDING_MSG;
5189            msg.obj = map;
5190            msg.arg1 = aboveSystem ? 1 : 0;
5191            map.put("app", app);
5192            if (activity != null) {
5193                map.put("activity", activity);
5194            }
5195
5196            mHandler.sendMessage(msg);
5197        }
5198    }
5199
5200    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5201        if (!mLaunchWarningShown) {
5202            mLaunchWarningShown = true;
5203            mHandler.post(new Runnable() {
5204                @Override
5205                public void run() {
5206                    synchronized (ActivityManagerService.this) {
5207                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5208                        d.show();
5209                        mHandler.postDelayed(new Runnable() {
5210                            @Override
5211                            public void run() {
5212                                synchronized (ActivityManagerService.this) {
5213                                    d.dismiss();
5214                                    mLaunchWarningShown = false;
5215                                }
5216                            }
5217                        }, 4000);
5218                    }
5219                }
5220            });
5221        }
5222    }
5223
5224    @Override
5225    public boolean clearApplicationUserData(final String packageName,
5226            final IPackageDataObserver observer, int userId) {
5227        enforceNotIsolatedCaller("clearApplicationUserData");
5228        int uid = Binder.getCallingUid();
5229        int pid = Binder.getCallingPid();
5230        userId = handleIncomingUser(pid, uid,
5231                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5232        long callingId = Binder.clearCallingIdentity();
5233        try {
5234            IPackageManager pm = AppGlobals.getPackageManager();
5235            int pkgUid = -1;
5236            synchronized(this) {
5237                try {
5238                    pkgUid = pm.getPackageUid(packageName, userId);
5239                } catch (RemoteException e) {
5240                }
5241                if (pkgUid == -1) {
5242                    Slog.w(TAG, "Invalid packageName: " + packageName);
5243                    if (observer != null) {
5244                        try {
5245                            observer.onRemoveCompleted(packageName, false);
5246                        } catch (RemoteException e) {
5247                            Slog.i(TAG, "Observer no longer exists.");
5248                        }
5249                    }
5250                    return false;
5251                }
5252                if (uid == pkgUid || checkComponentPermission(
5253                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5254                        pid, uid, -1, true)
5255                        == PackageManager.PERMISSION_GRANTED) {
5256                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5257                } else {
5258                    throw new SecurityException("PID " + pid + " does not have permission "
5259                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5260                                    + " of package " + packageName);
5261                }
5262
5263                // Remove all tasks match the cleared application package and user
5264                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5265                    final TaskRecord tr = mRecentTasks.get(i);
5266                    final String taskPackageName =
5267                            tr.getBaseIntent().getComponent().getPackageName();
5268                    if (tr.userId != userId) continue;
5269                    if (!taskPackageName.equals(packageName)) continue;
5270                    removeTaskByIdLocked(tr.taskId, 0);
5271                }
5272            }
5273
5274            try {
5275                // Clear application user data
5276                pm.clearApplicationUserData(packageName, observer, userId);
5277
5278                synchronized(this) {
5279                    // Remove all permissions granted from/to this package
5280                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5281                }
5282
5283                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5284                        Uri.fromParts("package", packageName, null));
5285                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5286                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5287                        null, null, 0, null, null, null, false, false, userId);
5288            } catch (RemoteException e) {
5289            }
5290        } finally {
5291            Binder.restoreCallingIdentity(callingId);
5292        }
5293        return true;
5294    }
5295
5296    @Override
5297    public void killBackgroundProcesses(final String packageName, int userId) {
5298        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5299                != PackageManager.PERMISSION_GRANTED &&
5300                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5301                        != PackageManager.PERMISSION_GRANTED) {
5302            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5303                    + Binder.getCallingPid()
5304                    + ", uid=" + Binder.getCallingUid()
5305                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5306            Slog.w(TAG, msg);
5307            throw new SecurityException(msg);
5308        }
5309
5310        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5311                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5312        long callingId = Binder.clearCallingIdentity();
5313        try {
5314            IPackageManager pm = AppGlobals.getPackageManager();
5315            synchronized(this) {
5316                int appId = -1;
5317                try {
5318                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5319                } catch (RemoteException e) {
5320                }
5321                if (appId == -1) {
5322                    Slog.w(TAG, "Invalid packageName: " + packageName);
5323                    return;
5324                }
5325                killPackageProcessesLocked(packageName, appId, userId,
5326                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5327            }
5328        } finally {
5329            Binder.restoreCallingIdentity(callingId);
5330        }
5331    }
5332
5333    @Override
5334    public void killAllBackgroundProcesses() {
5335        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5336                != PackageManager.PERMISSION_GRANTED) {
5337            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5338                    + Binder.getCallingPid()
5339                    + ", uid=" + Binder.getCallingUid()
5340                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5341            Slog.w(TAG, msg);
5342            throw new SecurityException(msg);
5343        }
5344
5345        long callingId = Binder.clearCallingIdentity();
5346        try {
5347            synchronized(this) {
5348                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5349                final int NP = mProcessNames.getMap().size();
5350                for (int ip=0; ip<NP; ip++) {
5351                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5352                    final int NA = apps.size();
5353                    for (int ia=0; ia<NA; ia++) {
5354                        ProcessRecord app = apps.valueAt(ia);
5355                        if (app.persistent) {
5356                            // we don't kill persistent processes
5357                            continue;
5358                        }
5359                        if (app.removed) {
5360                            procs.add(app);
5361                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5362                            app.removed = true;
5363                            procs.add(app);
5364                        }
5365                    }
5366                }
5367
5368                int N = procs.size();
5369                for (int i=0; i<N; i++) {
5370                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5371                }
5372                mAllowLowerMemLevel = true;
5373                updateOomAdjLocked();
5374                doLowMemReportIfNeededLocked(null);
5375            }
5376        } finally {
5377            Binder.restoreCallingIdentity(callingId);
5378        }
5379    }
5380
5381    @Override
5382    public void forceStopPackage(final String packageName, int userId) {
5383        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5384                != PackageManager.PERMISSION_GRANTED) {
5385            String msg = "Permission Denial: forceStopPackage() from pid="
5386                    + Binder.getCallingPid()
5387                    + ", uid=" + Binder.getCallingUid()
5388                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5389            Slog.w(TAG, msg);
5390            throw new SecurityException(msg);
5391        }
5392        final int callingPid = Binder.getCallingPid();
5393        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5394                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5395        long callingId = Binder.clearCallingIdentity();
5396        try {
5397            IPackageManager pm = AppGlobals.getPackageManager();
5398            synchronized(this) {
5399                int[] users = userId == UserHandle.USER_ALL
5400                        ? getUsersLocked() : new int[] { userId };
5401                for (int user : users) {
5402                    int pkgUid = -1;
5403                    try {
5404                        pkgUid = pm.getPackageUid(packageName, user);
5405                    } catch (RemoteException e) {
5406                    }
5407                    if (pkgUid == -1) {
5408                        Slog.w(TAG, "Invalid packageName: " + packageName);
5409                        continue;
5410                    }
5411                    try {
5412                        pm.setPackageStoppedState(packageName, true, user);
5413                    } catch (RemoteException e) {
5414                    } catch (IllegalArgumentException e) {
5415                        Slog.w(TAG, "Failed trying to unstop package "
5416                                + packageName + ": " + e);
5417                    }
5418                    if (isUserRunningLocked(user, false)) {
5419                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5420                    }
5421                }
5422            }
5423        } finally {
5424            Binder.restoreCallingIdentity(callingId);
5425        }
5426    }
5427
5428    @Override
5429    public void addPackageDependency(String packageName) {
5430        synchronized (this) {
5431            int callingPid = Binder.getCallingPid();
5432            if (callingPid == Process.myPid()) {
5433                //  Yeah, um, no.
5434                Slog.w(TAG, "Can't addPackageDependency on system process");
5435                return;
5436            }
5437            ProcessRecord proc;
5438            synchronized (mPidsSelfLocked) {
5439                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5440            }
5441            if (proc != null) {
5442                if (proc.pkgDeps == null) {
5443                    proc.pkgDeps = new ArraySet<String>(1);
5444                }
5445                proc.pkgDeps.add(packageName);
5446            }
5447        }
5448    }
5449
5450    /*
5451     * The pkg name and app id have to be specified.
5452     */
5453    @Override
5454    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5455        if (pkg == null) {
5456            return;
5457        }
5458        // Make sure the uid is valid.
5459        if (appid < 0) {
5460            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5461            return;
5462        }
5463        int callerUid = Binder.getCallingUid();
5464        // Only the system server can kill an application
5465        if (callerUid == Process.SYSTEM_UID) {
5466            // Post an aysnc message to kill the application
5467            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5468            msg.arg1 = appid;
5469            msg.arg2 = 0;
5470            Bundle bundle = new Bundle();
5471            bundle.putString("pkg", pkg);
5472            bundle.putString("reason", reason);
5473            msg.obj = bundle;
5474            mHandler.sendMessage(msg);
5475        } else {
5476            throw new SecurityException(callerUid + " cannot kill pkg: " +
5477                    pkg);
5478        }
5479    }
5480
5481    @Override
5482    public void closeSystemDialogs(String reason) {
5483        enforceNotIsolatedCaller("closeSystemDialogs");
5484
5485        final int pid = Binder.getCallingPid();
5486        final int uid = Binder.getCallingUid();
5487        final long origId = Binder.clearCallingIdentity();
5488        try {
5489            synchronized (this) {
5490                // Only allow this from foreground processes, so that background
5491                // applications can't abuse it to prevent system UI from being shown.
5492                if (uid >= Process.FIRST_APPLICATION_UID) {
5493                    ProcessRecord proc;
5494                    synchronized (mPidsSelfLocked) {
5495                        proc = mPidsSelfLocked.get(pid);
5496                    }
5497                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5498                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5499                                + " from background process " + proc);
5500                        return;
5501                    }
5502                }
5503                closeSystemDialogsLocked(reason);
5504            }
5505        } finally {
5506            Binder.restoreCallingIdentity(origId);
5507        }
5508    }
5509
5510    void closeSystemDialogsLocked(String reason) {
5511        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5512        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5513                | Intent.FLAG_RECEIVER_FOREGROUND);
5514        if (reason != null) {
5515            intent.putExtra("reason", reason);
5516        }
5517        mWindowManager.closeSystemDialogs(reason);
5518
5519        mStackSupervisor.closeSystemDialogsLocked();
5520
5521        broadcastIntentLocked(null, null, intent, null,
5522                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5523                Process.SYSTEM_UID, UserHandle.USER_ALL);
5524    }
5525
5526    @Override
5527    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5528        enforceNotIsolatedCaller("getProcessMemoryInfo");
5529        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5530        for (int i=pids.length-1; i>=0; i--) {
5531            ProcessRecord proc;
5532            int oomAdj;
5533            synchronized (this) {
5534                synchronized (mPidsSelfLocked) {
5535                    proc = mPidsSelfLocked.get(pids[i]);
5536                    oomAdj = proc != null ? proc.setAdj : 0;
5537                }
5538            }
5539            infos[i] = new Debug.MemoryInfo();
5540            Debug.getMemoryInfo(pids[i], infos[i]);
5541            if (proc != null) {
5542                synchronized (this) {
5543                    if (proc.thread != null && proc.setAdj == oomAdj) {
5544                        // Record this for posterity if the process has been stable.
5545                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5546                                infos[i].getTotalUss(), false, proc.pkgList);
5547                    }
5548                }
5549            }
5550        }
5551        return infos;
5552    }
5553
5554    @Override
5555    public long[] getProcessPss(int[] pids) {
5556        enforceNotIsolatedCaller("getProcessPss");
5557        long[] pss = new long[pids.length];
5558        for (int i=pids.length-1; i>=0; i--) {
5559            ProcessRecord proc;
5560            int oomAdj;
5561            synchronized (this) {
5562                synchronized (mPidsSelfLocked) {
5563                    proc = mPidsSelfLocked.get(pids[i]);
5564                    oomAdj = proc != null ? proc.setAdj : 0;
5565                }
5566            }
5567            long[] tmpUss = new long[1];
5568            pss[i] = Debug.getPss(pids[i], tmpUss);
5569            if (proc != null) {
5570                synchronized (this) {
5571                    if (proc.thread != null && proc.setAdj == oomAdj) {
5572                        // Record this for posterity if the process has been stable.
5573                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5574                    }
5575                }
5576            }
5577        }
5578        return pss;
5579    }
5580
5581    @Override
5582    public void killApplicationProcess(String processName, int uid) {
5583        if (processName == null) {
5584            return;
5585        }
5586
5587        int callerUid = Binder.getCallingUid();
5588        // Only the system server can kill an application
5589        if (callerUid == Process.SYSTEM_UID) {
5590            synchronized (this) {
5591                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5592                if (app != null && app.thread != null) {
5593                    try {
5594                        app.thread.scheduleSuicide();
5595                    } catch (RemoteException e) {
5596                        // If the other end already died, then our work here is done.
5597                    }
5598                } else {
5599                    Slog.w(TAG, "Process/uid not found attempting kill of "
5600                            + processName + " / " + uid);
5601                }
5602            }
5603        } else {
5604            throw new SecurityException(callerUid + " cannot kill app process: " +
5605                    processName);
5606        }
5607    }
5608
5609    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5610        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5611                false, true, false, false, UserHandle.getUserId(uid), reason);
5612        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5613                Uri.fromParts("package", packageName, null));
5614        if (!mProcessesReady) {
5615            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5616                    | Intent.FLAG_RECEIVER_FOREGROUND);
5617        }
5618        intent.putExtra(Intent.EXTRA_UID, uid);
5619        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5620        broadcastIntentLocked(null, null, intent,
5621                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5622                false, false,
5623                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5624    }
5625
5626    private void forceStopUserLocked(int userId, String reason) {
5627        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5628        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5629        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5630                | Intent.FLAG_RECEIVER_FOREGROUND);
5631        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5632        broadcastIntentLocked(null, null, intent,
5633                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5634                false, false,
5635                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5636    }
5637
5638    private final boolean killPackageProcessesLocked(String packageName, int appId,
5639            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5640            boolean doit, boolean evenPersistent, String reason) {
5641        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5642
5643        // Remove all processes this package may have touched: all with the
5644        // same UID (except for the system or root user), and all whose name
5645        // matches the package name.
5646        final int NP = mProcessNames.getMap().size();
5647        for (int ip=0; ip<NP; ip++) {
5648            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5649            final int NA = apps.size();
5650            for (int ia=0; ia<NA; ia++) {
5651                ProcessRecord app = apps.valueAt(ia);
5652                if (app.persistent && !evenPersistent) {
5653                    // we don't kill persistent processes
5654                    continue;
5655                }
5656                if (app.removed) {
5657                    if (doit) {
5658                        procs.add(app);
5659                    }
5660                    continue;
5661                }
5662
5663                // Skip process if it doesn't meet our oom adj requirement.
5664                if (app.setAdj < minOomAdj) {
5665                    continue;
5666                }
5667
5668                // If no package is specified, we call all processes under the
5669                // give user id.
5670                if (packageName == null) {
5671                    if (app.userId != userId) {
5672                        continue;
5673                    }
5674                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5675                        continue;
5676                    }
5677                // Package has been specified, we want to hit all processes
5678                // that match it.  We need to qualify this by the processes
5679                // that are running under the specified app and user ID.
5680                } else {
5681                    final boolean isDep = app.pkgDeps != null
5682                            && app.pkgDeps.contains(packageName);
5683                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5684                        continue;
5685                    }
5686                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5687                        continue;
5688                    }
5689                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5690                        continue;
5691                    }
5692                }
5693
5694                // Process has passed all conditions, kill it!
5695                if (!doit) {
5696                    return true;
5697                }
5698                app.removed = true;
5699                procs.add(app);
5700            }
5701        }
5702
5703        int N = procs.size();
5704        for (int i=0; i<N; i++) {
5705            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5706        }
5707        updateOomAdjLocked();
5708        return N > 0;
5709    }
5710
5711    private final boolean forceStopPackageLocked(String name, int appId,
5712            boolean callerWillRestart, boolean purgeCache, boolean doit,
5713            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5714        int i;
5715        int N;
5716
5717        if (userId == UserHandle.USER_ALL && name == null) {
5718            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5719        }
5720
5721        if (appId < 0 && name != null) {
5722            try {
5723                appId = UserHandle.getAppId(
5724                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5725            } catch (RemoteException e) {
5726            }
5727        }
5728
5729        if (doit) {
5730            if (name != null) {
5731                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5732                        + " user=" + userId + ": " + reason);
5733            } else {
5734                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5735            }
5736
5737            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5738            for (int ip=pmap.size()-1; ip>=0; ip--) {
5739                SparseArray<Long> ba = pmap.valueAt(ip);
5740                for (i=ba.size()-1; i>=0; i--) {
5741                    boolean remove = false;
5742                    final int entUid = ba.keyAt(i);
5743                    if (name != null) {
5744                        if (userId == UserHandle.USER_ALL) {
5745                            if (UserHandle.getAppId(entUid) == appId) {
5746                                remove = true;
5747                            }
5748                        } else {
5749                            if (entUid == UserHandle.getUid(userId, appId)) {
5750                                remove = true;
5751                            }
5752                        }
5753                    } else if (UserHandle.getUserId(entUid) == userId) {
5754                        remove = true;
5755                    }
5756                    if (remove) {
5757                        ba.removeAt(i);
5758                    }
5759                }
5760                if (ba.size() == 0) {
5761                    pmap.removeAt(ip);
5762                }
5763            }
5764        }
5765
5766        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5767                -100, callerWillRestart, true, doit, evenPersistent,
5768                name == null ? ("stop user " + userId) : ("stop " + name));
5769
5770        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5771            if (!doit) {
5772                return true;
5773            }
5774            didSomething = true;
5775        }
5776
5777        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5778            if (!doit) {
5779                return true;
5780            }
5781            didSomething = true;
5782        }
5783
5784        if (name == null) {
5785            // Remove all sticky broadcasts from this user.
5786            mStickyBroadcasts.remove(userId);
5787        }
5788
5789        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5790        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5791                userId, providers)) {
5792            if (!doit) {
5793                return true;
5794            }
5795            didSomething = true;
5796        }
5797        N = providers.size();
5798        for (i=0; i<N; i++) {
5799            removeDyingProviderLocked(null, providers.get(i), true);
5800        }
5801
5802        // Remove transient permissions granted from/to this package/user
5803        removeUriPermissionsForPackageLocked(name, userId, false);
5804
5805        if (name == null || uninstalling) {
5806            // Remove pending intents.  For now we only do this when force
5807            // stopping users, because we have some problems when doing this
5808            // for packages -- app widgets are not currently cleaned up for
5809            // such packages, so they can be left with bad pending intents.
5810            if (mIntentSenderRecords.size() > 0) {
5811                Iterator<WeakReference<PendingIntentRecord>> it
5812                        = mIntentSenderRecords.values().iterator();
5813                while (it.hasNext()) {
5814                    WeakReference<PendingIntentRecord> wpir = it.next();
5815                    if (wpir == null) {
5816                        it.remove();
5817                        continue;
5818                    }
5819                    PendingIntentRecord pir = wpir.get();
5820                    if (pir == null) {
5821                        it.remove();
5822                        continue;
5823                    }
5824                    if (name == null) {
5825                        // Stopping user, remove all objects for the user.
5826                        if (pir.key.userId != userId) {
5827                            // Not the same user, skip it.
5828                            continue;
5829                        }
5830                    } else {
5831                        if (UserHandle.getAppId(pir.uid) != appId) {
5832                            // Different app id, skip it.
5833                            continue;
5834                        }
5835                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5836                            // Different user, skip it.
5837                            continue;
5838                        }
5839                        if (!pir.key.packageName.equals(name)) {
5840                            // Different package, skip it.
5841                            continue;
5842                        }
5843                    }
5844                    if (!doit) {
5845                        return true;
5846                    }
5847                    didSomething = true;
5848                    it.remove();
5849                    pir.canceled = true;
5850                    if (pir.key.activity != null) {
5851                        pir.key.activity.pendingResults.remove(pir.ref);
5852                    }
5853                }
5854            }
5855        }
5856
5857        if (doit) {
5858            if (purgeCache && name != null) {
5859                AttributeCache ac = AttributeCache.instance();
5860                if (ac != null) {
5861                    ac.removePackage(name);
5862                }
5863            }
5864            if (mBooted) {
5865                mStackSupervisor.resumeTopActivitiesLocked();
5866                mStackSupervisor.scheduleIdleLocked();
5867            }
5868        }
5869
5870        return didSomething;
5871    }
5872
5873    private final boolean removeProcessLocked(ProcessRecord app,
5874            boolean callerWillRestart, boolean allowRestart, String reason) {
5875        final String name = app.processName;
5876        final int uid = app.uid;
5877        if (DEBUG_PROCESSES) Slog.d(
5878            TAG, "Force removing proc " + app.toShortString() + " (" + name
5879            + "/" + uid + ")");
5880
5881        mProcessNames.remove(name, uid);
5882        mIsolatedProcesses.remove(app.uid);
5883        if (mHeavyWeightProcess == app) {
5884            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5885                    mHeavyWeightProcess.userId, 0));
5886            mHeavyWeightProcess = null;
5887        }
5888        boolean needRestart = false;
5889        if (app.pid > 0 && app.pid != MY_PID) {
5890            int pid = app.pid;
5891            synchronized (mPidsSelfLocked) {
5892                mPidsSelfLocked.remove(pid);
5893                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5894            }
5895            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5896            if (app.isolated) {
5897                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5898            }
5899            app.kill(reason, true);
5900            handleAppDiedLocked(app, true, allowRestart);
5901            removeLruProcessLocked(app);
5902
5903            if (app.persistent && !app.isolated) {
5904                if (!callerWillRestart) {
5905                    addAppLocked(app.info, false, null /* ABI override */);
5906                } else {
5907                    needRestart = true;
5908                }
5909            }
5910        } else {
5911            mRemovedProcesses.add(app);
5912        }
5913
5914        return needRestart;
5915    }
5916
5917    private final void processStartTimedOutLocked(ProcessRecord app) {
5918        final int pid = app.pid;
5919        boolean gone = false;
5920        synchronized (mPidsSelfLocked) {
5921            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5922            if (knownApp != null && knownApp.thread == null) {
5923                mPidsSelfLocked.remove(pid);
5924                gone = true;
5925            }
5926        }
5927
5928        if (gone) {
5929            Slog.w(TAG, "Process " + app + " failed to attach");
5930            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5931                    pid, app.uid, app.processName);
5932            mProcessNames.remove(app.processName, app.uid);
5933            mIsolatedProcesses.remove(app.uid);
5934            if (mHeavyWeightProcess == app) {
5935                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5936                        mHeavyWeightProcess.userId, 0));
5937                mHeavyWeightProcess = null;
5938            }
5939            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5940            if (app.isolated) {
5941                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5942            }
5943            // Take care of any launching providers waiting for this process.
5944            checkAppInLaunchingProvidersLocked(app, true);
5945            // Take care of any services that are waiting for the process.
5946            mServices.processStartTimedOutLocked(app);
5947            app.kill("start timeout", true);
5948            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5949                Slog.w(TAG, "Unattached app died before backup, skipping");
5950                try {
5951                    IBackupManager bm = IBackupManager.Stub.asInterface(
5952                            ServiceManager.getService(Context.BACKUP_SERVICE));
5953                    bm.agentDisconnected(app.info.packageName);
5954                } catch (RemoteException e) {
5955                    // Can't happen; the backup manager is local
5956                }
5957            }
5958            if (isPendingBroadcastProcessLocked(pid)) {
5959                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5960                skipPendingBroadcastLocked(pid);
5961            }
5962        } else {
5963            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5964        }
5965    }
5966
5967    private final boolean attachApplicationLocked(IApplicationThread thread,
5968            int pid) {
5969
5970        // Find the application record that is being attached...  either via
5971        // the pid if we are running in multiple processes, or just pull the
5972        // next app record if we are emulating process with anonymous threads.
5973        ProcessRecord app;
5974        if (pid != MY_PID && pid >= 0) {
5975            synchronized (mPidsSelfLocked) {
5976                app = mPidsSelfLocked.get(pid);
5977            }
5978        } else {
5979            app = null;
5980        }
5981
5982        if (app == null) {
5983            Slog.w(TAG, "No pending application record for pid " + pid
5984                    + " (IApplicationThread " + thread + "); dropping process");
5985            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5986            if (pid > 0 && pid != MY_PID) {
5987                Process.killProcessQuiet(pid);
5988                //TODO: Process.killProcessGroup(app.info.uid, pid);
5989            } else {
5990                try {
5991                    thread.scheduleExit();
5992                } catch (Exception e) {
5993                    // Ignore exceptions.
5994                }
5995            }
5996            return false;
5997        }
5998
5999        // If this application record is still attached to a previous
6000        // process, clean it up now.
6001        if (app.thread != null) {
6002            handleAppDiedLocked(app, true, true);
6003        }
6004
6005        // Tell the process all about itself.
6006
6007        if (localLOGV) Slog.v(
6008                TAG, "Binding process pid " + pid + " to record " + app);
6009
6010        final String processName = app.processName;
6011        try {
6012            AppDeathRecipient adr = new AppDeathRecipient(
6013                    app, pid, thread);
6014            thread.asBinder().linkToDeath(adr, 0);
6015            app.deathRecipient = adr;
6016        } catch (RemoteException e) {
6017            app.resetPackageList(mProcessStats);
6018            startProcessLocked(app, "link fail", processName);
6019            return false;
6020        }
6021
6022        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6023
6024        app.makeActive(thread, mProcessStats);
6025        app.curAdj = app.setAdj = -100;
6026        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6027        app.forcingToForeground = null;
6028        updateProcessForegroundLocked(app, false, false);
6029        app.hasShownUi = false;
6030        app.debugging = false;
6031        app.cached = false;
6032
6033        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6034
6035        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6036        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6037
6038        if (!normalMode) {
6039            Slog.i(TAG, "Launching preboot mode app: " + app);
6040        }
6041
6042        if (localLOGV) Slog.v(
6043            TAG, "New app record " + app
6044            + " thread=" + thread.asBinder() + " pid=" + pid);
6045        try {
6046            int testMode = IApplicationThread.DEBUG_OFF;
6047            if (mDebugApp != null && mDebugApp.equals(processName)) {
6048                testMode = mWaitForDebugger
6049                    ? IApplicationThread.DEBUG_WAIT
6050                    : IApplicationThread.DEBUG_ON;
6051                app.debugging = true;
6052                if (mDebugTransient) {
6053                    mDebugApp = mOrigDebugApp;
6054                    mWaitForDebugger = mOrigWaitForDebugger;
6055                }
6056            }
6057            String profileFile = app.instrumentationProfileFile;
6058            ParcelFileDescriptor profileFd = null;
6059            int samplingInterval = 0;
6060            boolean profileAutoStop = false;
6061            if (mProfileApp != null && mProfileApp.equals(processName)) {
6062                mProfileProc = app;
6063                profileFile = mProfileFile;
6064                profileFd = mProfileFd;
6065                samplingInterval = mSamplingInterval;
6066                profileAutoStop = mAutoStopProfiler;
6067            }
6068            boolean enableOpenGlTrace = false;
6069            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6070                enableOpenGlTrace = true;
6071                mOpenGlTraceApp = null;
6072            }
6073
6074            // If the app is being launched for restore or full backup, set it up specially
6075            boolean isRestrictedBackupMode = false;
6076            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6077                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6078                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6079                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6080            }
6081
6082            ensurePackageDexOpt(app.instrumentationInfo != null
6083                    ? app.instrumentationInfo.packageName
6084                    : app.info.packageName);
6085            if (app.instrumentationClass != null) {
6086                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6087            }
6088            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6089                    + processName + " with config " + mConfiguration);
6090            ApplicationInfo appInfo = app.instrumentationInfo != null
6091                    ? app.instrumentationInfo : app.info;
6092            app.compat = compatibilityInfoForPackageLocked(appInfo);
6093            if (profileFd != null) {
6094                profileFd = profileFd.dup();
6095            }
6096            ProfilerInfo profilerInfo = profileFile == null ? null
6097                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6098            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6099                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6100                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6101                    isRestrictedBackupMode || !normalMode, app.persistent,
6102                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6103                    mCoreSettingsObserver.getCoreSettingsLocked());
6104            updateLruProcessLocked(app, false, null);
6105            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6106        } catch (Exception e) {
6107            // todo: Yikes!  What should we do?  For now we will try to
6108            // start another process, but that could easily get us in
6109            // an infinite loop of restarting processes...
6110            Slog.w(TAG, "Exception thrown during bind!", e);
6111
6112            app.resetPackageList(mProcessStats);
6113            app.unlinkDeathRecipient();
6114            startProcessLocked(app, "bind fail", processName);
6115            return false;
6116        }
6117
6118        // Remove this record from the list of starting applications.
6119        mPersistentStartingProcesses.remove(app);
6120        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6121                "Attach application locked removing on hold: " + app);
6122        mProcessesOnHold.remove(app);
6123
6124        boolean badApp = false;
6125        boolean didSomething = false;
6126
6127        // See if the top visible activity is waiting to run in this process...
6128        if (normalMode) {
6129            try {
6130                if (mStackSupervisor.attachApplicationLocked(app)) {
6131                    didSomething = true;
6132                }
6133            } catch (Exception e) {
6134                badApp = true;
6135            }
6136        }
6137
6138        // Find any services that should be running in this process...
6139        if (!badApp) {
6140            try {
6141                didSomething |= mServices.attachApplicationLocked(app, processName);
6142            } catch (Exception e) {
6143                badApp = true;
6144            }
6145        }
6146
6147        // Check if a next-broadcast receiver is in this process...
6148        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6149            try {
6150                didSomething |= sendPendingBroadcastsLocked(app);
6151            } catch (Exception e) {
6152                // If the app died trying to launch the receiver we declare it 'bad'
6153                badApp = true;
6154            }
6155        }
6156
6157        // Check whether the next backup agent is in this process...
6158        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6159            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6160            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6161            try {
6162                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6163                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6164                        mBackupTarget.backupMode);
6165            } catch (Exception e) {
6166                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6167                e.printStackTrace();
6168            }
6169        }
6170
6171        if (badApp) {
6172            // todo: Also need to kill application to deal with all
6173            // kinds of exceptions.
6174            handleAppDiedLocked(app, false, true);
6175            return false;
6176        }
6177
6178        if (!didSomething) {
6179            updateOomAdjLocked();
6180        }
6181
6182        return true;
6183    }
6184
6185    @Override
6186    public final void attachApplication(IApplicationThread thread) {
6187        synchronized (this) {
6188            int callingPid = Binder.getCallingPid();
6189            final long origId = Binder.clearCallingIdentity();
6190            attachApplicationLocked(thread, callingPid);
6191            Binder.restoreCallingIdentity(origId);
6192        }
6193    }
6194
6195    @Override
6196    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6197        final long origId = Binder.clearCallingIdentity();
6198        synchronized (this) {
6199            ActivityStack stack = ActivityRecord.getStackLocked(token);
6200            if (stack != null) {
6201                ActivityRecord r =
6202                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6203                if (stopProfiling) {
6204                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6205                        try {
6206                            mProfileFd.close();
6207                        } catch (IOException e) {
6208                        }
6209                        clearProfilerLocked();
6210                    }
6211                }
6212            }
6213        }
6214        Binder.restoreCallingIdentity(origId);
6215    }
6216
6217    void postEnableScreenAfterBootLocked() {
6218        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6219    }
6220
6221    void enableScreenAfterBoot() {
6222        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6223                SystemClock.uptimeMillis());
6224        mWindowManager.enableScreenAfterBoot();
6225
6226        synchronized (this) {
6227            updateEventDispatchingLocked();
6228        }
6229    }
6230
6231    @Override
6232    public void showBootMessage(final CharSequence msg, final boolean always) {
6233        enforceNotIsolatedCaller("showBootMessage");
6234        mWindowManager.showBootMessage(msg, always);
6235    }
6236
6237    @Override
6238    public void keyguardWaitingForActivityDrawn() {
6239        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6240        final long token = Binder.clearCallingIdentity();
6241        try {
6242            synchronized (this) {
6243                if (DEBUG_LOCKSCREEN) logLockScreen("");
6244                mWindowManager.keyguardWaitingForActivityDrawn();
6245            }
6246        } finally {
6247            Binder.restoreCallingIdentity(token);
6248        }
6249    }
6250
6251    final void finishBooting() {
6252        synchronized (this) {
6253            if (!mBootAnimationComplete) {
6254                mCallFinishBooting = true;
6255                return;
6256            }
6257            mCallFinishBooting = false;
6258        }
6259
6260        // Register receivers to handle package update events
6261        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6262
6263        // Let system services know.
6264        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6265
6266        synchronized (this) {
6267            // Ensure that any processes we had put on hold are now started
6268            // up.
6269            final int NP = mProcessesOnHold.size();
6270            if (NP > 0) {
6271                ArrayList<ProcessRecord> procs =
6272                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6273                for (int ip=0; ip<NP; ip++) {
6274                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6275                            + procs.get(ip));
6276                    startProcessLocked(procs.get(ip), "on-hold", null);
6277                }
6278            }
6279
6280            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6281                // Start looking for apps that are abusing wake locks.
6282                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6283                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6284                // Tell anyone interested that we are done booting!
6285                SystemProperties.set("sys.boot_completed", "1");
6286                SystemProperties.set("dev.bootcomplete", "1");
6287                for (int i=0; i<mStartedUsers.size(); i++) {
6288                    UserStartedState uss = mStartedUsers.valueAt(i);
6289                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6290                        uss.mState = UserStartedState.STATE_RUNNING;
6291                        final int userId = mStartedUsers.keyAt(i);
6292                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6293                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6294                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6295                        broadcastIntentLocked(null, null, intent, null,
6296                                new IIntentReceiver.Stub() {
6297                                    @Override
6298                                    public void performReceive(Intent intent, int resultCode,
6299                                            String data, Bundle extras, boolean ordered,
6300                                            boolean sticky, int sendingUser) {
6301                                        synchronized (ActivityManagerService.this) {
6302                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6303                                                    true, false);
6304                                        }
6305                                    }
6306                                },
6307                                0, null, null,
6308                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6309                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6310                                userId);
6311                    }
6312                }
6313                scheduleStartProfilesLocked();
6314            }
6315        }
6316    }
6317
6318    @Override
6319    public void bootAnimationComplete() {
6320        final boolean callFinishBooting;
6321        synchronized (this) {
6322            callFinishBooting = mCallFinishBooting;
6323            mBootAnimationComplete = true;
6324        }
6325        if (callFinishBooting) {
6326            finishBooting();
6327        }
6328    }
6329
6330    final void ensureBootCompleted() {
6331        boolean booting;
6332        boolean enableScreen;
6333        synchronized (this) {
6334            booting = mBooting;
6335            mBooting = false;
6336            enableScreen = !mBooted;
6337            mBooted = true;
6338        }
6339
6340        if (booting) {
6341            finishBooting();
6342        }
6343
6344        if (enableScreen) {
6345            enableScreenAfterBoot();
6346        }
6347    }
6348
6349    @Override
6350    public final void activityResumed(IBinder token) {
6351        final long origId = Binder.clearCallingIdentity();
6352        synchronized(this) {
6353            ActivityStack stack = ActivityRecord.getStackLocked(token);
6354            if (stack != null) {
6355                ActivityRecord.activityResumedLocked(token);
6356            }
6357        }
6358        Binder.restoreCallingIdentity(origId);
6359    }
6360
6361    @Override
6362    public final void activityPaused(IBinder token) {
6363        final long origId = Binder.clearCallingIdentity();
6364        synchronized(this) {
6365            ActivityStack stack = ActivityRecord.getStackLocked(token);
6366            if (stack != null) {
6367                stack.activityPausedLocked(token, false);
6368            }
6369        }
6370        Binder.restoreCallingIdentity(origId);
6371    }
6372
6373    @Override
6374    public final void activityStopped(IBinder token, Bundle icicle,
6375            PersistableBundle persistentState, CharSequence description) {
6376        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6377
6378        // Refuse possible leaked file descriptors
6379        if (icicle != null && icicle.hasFileDescriptors()) {
6380            throw new IllegalArgumentException("File descriptors passed in Bundle");
6381        }
6382
6383        final long origId = Binder.clearCallingIdentity();
6384
6385        synchronized (this) {
6386            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6387            if (r != null) {
6388                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6389            }
6390        }
6391
6392        trimApplications();
6393
6394        Binder.restoreCallingIdentity(origId);
6395    }
6396
6397    @Override
6398    public final void activityDestroyed(IBinder token) {
6399        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6400        synchronized (this) {
6401            ActivityStack stack = ActivityRecord.getStackLocked(token);
6402            if (stack != null) {
6403                stack.activityDestroyedLocked(token);
6404            }
6405        }
6406    }
6407
6408    @Override
6409    public final void backgroundResourcesReleased(IBinder token) {
6410        final long origId = Binder.clearCallingIdentity();
6411        try {
6412            synchronized (this) {
6413                ActivityStack stack = ActivityRecord.getStackLocked(token);
6414                if (stack != null) {
6415                    stack.backgroundResourcesReleased(token);
6416                }
6417            }
6418        } finally {
6419            Binder.restoreCallingIdentity(origId);
6420        }
6421    }
6422
6423    @Override
6424    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6425        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6426    }
6427
6428    @Override
6429    public final void notifyEnterAnimationComplete(IBinder token) {
6430        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6431    }
6432
6433    @Override
6434    public String getCallingPackage(IBinder token) {
6435        synchronized (this) {
6436            ActivityRecord r = getCallingRecordLocked(token);
6437            return r != null ? r.info.packageName : null;
6438        }
6439    }
6440
6441    @Override
6442    public ComponentName getCallingActivity(IBinder token) {
6443        synchronized (this) {
6444            ActivityRecord r = getCallingRecordLocked(token);
6445            return r != null ? r.intent.getComponent() : null;
6446        }
6447    }
6448
6449    private ActivityRecord getCallingRecordLocked(IBinder token) {
6450        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6451        if (r == null) {
6452            return null;
6453        }
6454        return r.resultTo;
6455    }
6456
6457    @Override
6458    public ComponentName getActivityClassForToken(IBinder token) {
6459        synchronized(this) {
6460            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6461            if (r == null) {
6462                return null;
6463            }
6464            return r.intent.getComponent();
6465        }
6466    }
6467
6468    @Override
6469    public String getPackageForToken(IBinder token) {
6470        synchronized(this) {
6471            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6472            if (r == null) {
6473                return null;
6474            }
6475            return r.packageName;
6476        }
6477    }
6478
6479    @Override
6480    public IIntentSender getIntentSender(int type,
6481            String packageName, IBinder token, String resultWho,
6482            int requestCode, Intent[] intents, String[] resolvedTypes,
6483            int flags, Bundle options, int userId) {
6484        enforceNotIsolatedCaller("getIntentSender");
6485        // Refuse possible leaked file descriptors
6486        if (intents != null) {
6487            if (intents.length < 1) {
6488                throw new IllegalArgumentException("Intents array length must be >= 1");
6489            }
6490            for (int i=0; i<intents.length; i++) {
6491                Intent intent = intents[i];
6492                if (intent != null) {
6493                    if (intent.hasFileDescriptors()) {
6494                        throw new IllegalArgumentException("File descriptors passed in Intent");
6495                    }
6496                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6497                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6498                        throw new IllegalArgumentException(
6499                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6500                    }
6501                    intents[i] = new Intent(intent);
6502                }
6503            }
6504            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6505                throw new IllegalArgumentException(
6506                        "Intent array length does not match resolvedTypes length");
6507            }
6508        }
6509        if (options != null) {
6510            if (options.hasFileDescriptors()) {
6511                throw new IllegalArgumentException("File descriptors passed in options");
6512            }
6513        }
6514
6515        synchronized(this) {
6516            int callingUid = Binder.getCallingUid();
6517            int origUserId = userId;
6518            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6519                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6520                    ALLOW_NON_FULL, "getIntentSender", null);
6521            if (origUserId == UserHandle.USER_CURRENT) {
6522                // We don't want to evaluate this until the pending intent is
6523                // actually executed.  However, we do want to always do the
6524                // security checking for it above.
6525                userId = UserHandle.USER_CURRENT;
6526            }
6527            try {
6528                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6529                    int uid = AppGlobals.getPackageManager()
6530                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6531                    if (!UserHandle.isSameApp(callingUid, uid)) {
6532                        String msg = "Permission Denial: getIntentSender() from pid="
6533                            + Binder.getCallingPid()
6534                            + ", uid=" + Binder.getCallingUid()
6535                            + ", (need uid=" + uid + ")"
6536                            + " is not allowed to send as package " + packageName;
6537                        Slog.w(TAG, msg);
6538                        throw new SecurityException(msg);
6539                    }
6540                }
6541
6542                return getIntentSenderLocked(type, packageName, callingUid, userId,
6543                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6544
6545            } catch (RemoteException e) {
6546                throw new SecurityException(e);
6547            }
6548        }
6549    }
6550
6551    IIntentSender getIntentSenderLocked(int type, String packageName,
6552            int callingUid, int userId, IBinder token, String resultWho,
6553            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6554            Bundle options) {
6555        if (DEBUG_MU)
6556            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6557        ActivityRecord activity = null;
6558        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6559            activity = ActivityRecord.isInStackLocked(token);
6560            if (activity == null) {
6561                return null;
6562            }
6563            if (activity.finishing) {
6564                return null;
6565            }
6566        }
6567
6568        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6569        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6570        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6571        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6572                |PendingIntent.FLAG_UPDATE_CURRENT);
6573
6574        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6575                type, packageName, activity, resultWho,
6576                requestCode, intents, resolvedTypes, flags, options, userId);
6577        WeakReference<PendingIntentRecord> ref;
6578        ref = mIntentSenderRecords.get(key);
6579        PendingIntentRecord rec = ref != null ? ref.get() : null;
6580        if (rec != null) {
6581            if (!cancelCurrent) {
6582                if (updateCurrent) {
6583                    if (rec.key.requestIntent != null) {
6584                        rec.key.requestIntent.replaceExtras(intents != null ?
6585                                intents[intents.length - 1] : null);
6586                    }
6587                    if (intents != null) {
6588                        intents[intents.length-1] = rec.key.requestIntent;
6589                        rec.key.allIntents = intents;
6590                        rec.key.allResolvedTypes = resolvedTypes;
6591                    } else {
6592                        rec.key.allIntents = null;
6593                        rec.key.allResolvedTypes = null;
6594                    }
6595                }
6596                return rec;
6597            }
6598            rec.canceled = true;
6599            mIntentSenderRecords.remove(key);
6600        }
6601        if (noCreate) {
6602            return rec;
6603        }
6604        rec = new PendingIntentRecord(this, key, callingUid);
6605        mIntentSenderRecords.put(key, rec.ref);
6606        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6607            if (activity.pendingResults == null) {
6608                activity.pendingResults
6609                        = new HashSet<WeakReference<PendingIntentRecord>>();
6610            }
6611            activity.pendingResults.add(rec.ref);
6612        }
6613        return rec;
6614    }
6615
6616    @Override
6617    public void cancelIntentSender(IIntentSender sender) {
6618        if (!(sender instanceof PendingIntentRecord)) {
6619            return;
6620        }
6621        synchronized(this) {
6622            PendingIntentRecord rec = (PendingIntentRecord)sender;
6623            try {
6624                int uid = AppGlobals.getPackageManager()
6625                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6626                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6627                    String msg = "Permission Denial: cancelIntentSender() from pid="
6628                        + Binder.getCallingPid()
6629                        + ", uid=" + Binder.getCallingUid()
6630                        + " is not allowed to cancel packges "
6631                        + rec.key.packageName;
6632                    Slog.w(TAG, msg);
6633                    throw new SecurityException(msg);
6634                }
6635            } catch (RemoteException e) {
6636                throw new SecurityException(e);
6637            }
6638            cancelIntentSenderLocked(rec, true);
6639        }
6640    }
6641
6642    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6643        rec.canceled = true;
6644        mIntentSenderRecords.remove(rec.key);
6645        if (cleanActivity && rec.key.activity != null) {
6646            rec.key.activity.pendingResults.remove(rec.ref);
6647        }
6648    }
6649
6650    @Override
6651    public String getPackageForIntentSender(IIntentSender pendingResult) {
6652        if (!(pendingResult instanceof PendingIntentRecord)) {
6653            return null;
6654        }
6655        try {
6656            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6657            return res.key.packageName;
6658        } catch (ClassCastException e) {
6659        }
6660        return null;
6661    }
6662
6663    @Override
6664    public int getUidForIntentSender(IIntentSender sender) {
6665        if (sender instanceof PendingIntentRecord) {
6666            try {
6667                PendingIntentRecord res = (PendingIntentRecord)sender;
6668                return res.uid;
6669            } catch (ClassCastException e) {
6670            }
6671        }
6672        return -1;
6673    }
6674
6675    @Override
6676    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6677        if (!(pendingResult instanceof PendingIntentRecord)) {
6678            return false;
6679        }
6680        try {
6681            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6682            if (res.key.allIntents == null) {
6683                return false;
6684            }
6685            for (int i=0; i<res.key.allIntents.length; i++) {
6686                Intent intent = res.key.allIntents[i];
6687                if (intent.getPackage() != null && intent.getComponent() != null) {
6688                    return false;
6689                }
6690            }
6691            return true;
6692        } catch (ClassCastException e) {
6693        }
6694        return false;
6695    }
6696
6697    @Override
6698    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6699        if (!(pendingResult instanceof PendingIntentRecord)) {
6700            return false;
6701        }
6702        try {
6703            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6704            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6705                return true;
6706            }
6707            return false;
6708        } catch (ClassCastException e) {
6709        }
6710        return false;
6711    }
6712
6713    @Override
6714    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6715        if (!(pendingResult instanceof PendingIntentRecord)) {
6716            return null;
6717        }
6718        try {
6719            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6720            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6721        } catch (ClassCastException e) {
6722        }
6723        return null;
6724    }
6725
6726    @Override
6727    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6728        if (!(pendingResult instanceof PendingIntentRecord)) {
6729            return null;
6730        }
6731        try {
6732            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6733            Intent intent = res.key.requestIntent;
6734            if (intent != null) {
6735                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6736                        || res.lastTagPrefix.equals(prefix))) {
6737                    return res.lastTag;
6738                }
6739                res.lastTagPrefix = prefix;
6740                StringBuilder sb = new StringBuilder(128);
6741                if (prefix != null) {
6742                    sb.append(prefix);
6743                }
6744                if (intent.getAction() != null) {
6745                    sb.append(intent.getAction());
6746                } else if (intent.getComponent() != null) {
6747                    intent.getComponent().appendShortString(sb);
6748                } else {
6749                    sb.append("?");
6750                }
6751                return res.lastTag = sb.toString();
6752            }
6753        } catch (ClassCastException e) {
6754        }
6755        return null;
6756    }
6757
6758    @Override
6759    public void setProcessLimit(int max) {
6760        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6761                "setProcessLimit()");
6762        synchronized (this) {
6763            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6764            mProcessLimitOverride = max;
6765        }
6766        trimApplications();
6767    }
6768
6769    @Override
6770    public int getProcessLimit() {
6771        synchronized (this) {
6772            return mProcessLimitOverride;
6773        }
6774    }
6775
6776    void foregroundTokenDied(ForegroundToken token) {
6777        synchronized (ActivityManagerService.this) {
6778            synchronized (mPidsSelfLocked) {
6779                ForegroundToken cur
6780                    = mForegroundProcesses.get(token.pid);
6781                if (cur != token) {
6782                    return;
6783                }
6784                mForegroundProcesses.remove(token.pid);
6785                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6786                if (pr == null) {
6787                    return;
6788                }
6789                pr.forcingToForeground = null;
6790                updateProcessForegroundLocked(pr, false, false);
6791            }
6792            updateOomAdjLocked();
6793        }
6794    }
6795
6796    @Override
6797    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6798        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6799                "setProcessForeground()");
6800        synchronized(this) {
6801            boolean changed = false;
6802
6803            synchronized (mPidsSelfLocked) {
6804                ProcessRecord pr = mPidsSelfLocked.get(pid);
6805                if (pr == null && isForeground) {
6806                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6807                    return;
6808                }
6809                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6810                if (oldToken != null) {
6811                    oldToken.token.unlinkToDeath(oldToken, 0);
6812                    mForegroundProcesses.remove(pid);
6813                    if (pr != null) {
6814                        pr.forcingToForeground = null;
6815                    }
6816                    changed = true;
6817                }
6818                if (isForeground && token != null) {
6819                    ForegroundToken newToken = new ForegroundToken() {
6820                        @Override
6821                        public void binderDied() {
6822                            foregroundTokenDied(this);
6823                        }
6824                    };
6825                    newToken.pid = pid;
6826                    newToken.token = token;
6827                    try {
6828                        token.linkToDeath(newToken, 0);
6829                        mForegroundProcesses.put(pid, newToken);
6830                        pr.forcingToForeground = token;
6831                        changed = true;
6832                    } catch (RemoteException e) {
6833                        // If the process died while doing this, we will later
6834                        // do the cleanup with the process death link.
6835                    }
6836                }
6837            }
6838
6839            if (changed) {
6840                updateOomAdjLocked();
6841            }
6842        }
6843    }
6844
6845    // =========================================================
6846    // PERMISSIONS
6847    // =========================================================
6848
6849    static class PermissionController extends IPermissionController.Stub {
6850        ActivityManagerService mActivityManagerService;
6851        PermissionController(ActivityManagerService activityManagerService) {
6852            mActivityManagerService = activityManagerService;
6853        }
6854
6855        @Override
6856        public boolean checkPermission(String permission, int pid, int uid) {
6857            return mActivityManagerService.checkPermission(permission, pid,
6858                    uid) == PackageManager.PERMISSION_GRANTED;
6859        }
6860    }
6861
6862    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6863        @Override
6864        public int checkComponentPermission(String permission, int pid, int uid,
6865                int owningUid, boolean exported) {
6866            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6867                    owningUid, exported);
6868        }
6869
6870        @Override
6871        public Object getAMSLock() {
6872            return ActivityManagerService.this;
6873        }
6874    }
6875
6876    /**
6877     * This can be called with or without the global lock held.
6878     */
6879    int checkComponentPermission(String permission, int pid, int uid,
6880            int owningUid, boolean exported) {
6881        // We might be performing an operation on behalf of an indirect binder
6882        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6883        // client identity accordingly before proceeding.
6884        Identity tlsIdentity = sCallerIdentity.get();
6885        if (tlsIdentity != null) {
6886            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6887                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6888            uid = tlsIdentity.uid;
6889            pid = tlsIdentity.pid;
6890        }
6891
6892        if (pid == MY_PID) {
6893            return PackageManager.PERMISSION_GRANTED;
6894        }
6895
6896        return ActivityManager.checkComponentPermission(permission, uid,
6897                owningUid, exported);
6898    }
6899
6900    /**
6901     * As the only public entry point for permissions checking, this method
6902     * can enforce the semantic that requesting a check on a null global
6903     * permission is automatically denied.  (Internally a null permission
6904     * string is used when calling {@link #checkComponentPermission} in cases
6905     * when only uid-based security is needed.)
6906     *
6907     * This can be called with or without the global lock held.
6908     */
6909    @Override
6910    public int checkPermission(String permission, int pid, int uid) {
6911        if (permission == null) {
6912            return PackageManager.PERMISSION_DENIED;
6913        }
6914        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6915    }
6916
6917    /**
6918     * Binder IPC calls go through the public entry point.
6919     * This can be called with or without the global lock held.
6920     */
6921    int checkCallingPermission(String permission) {
6922        return checkPermission(permission,
6923                Binder.getCallingPid(),
6924                UserHandle.getAppId(Binder.getCallingUid()));
6925    }
6926
6927    /**
6928     * This can be called with or without the global lock held.
6929     */
6930    void enforceCallingPermission(String permission, String func) {
6931        if (checkCallingPermission(permission)
6932                == PackageManager.PERMISSION_GRANTED) {
6933            return;
6934        }
6935
6936        String msg = "Permission Denial: " + func + " from pid="
6937                + Binder.getCallingPid()
6938                + ", uid=" + Binder.getCallingUid()
6939                + " requires " + permission;
6940        Slog.w(TAG, msg);
6941        throw new SecurityException(msg);
6942    }
6943
6944    /**
6945     * Determine if UID is holding permissions required to access {@link Uri} in
6946     * the given {@link ProviderInfo}. Final permission checking is always done
6947     * in {@link ContentProvider}.
6948     */
6949    private final boolean checkHoldingPermissionsLocked(
6950            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6951        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6952                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6953        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6954            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6955                    != PERMISSION_GRANTED) {
6956                return false;
6957            }
6958        }
6959        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6960    }
6961
6962    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6963            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6964        if (pi.applicationInfo.uid == uid) {
6965            return true;
6966        } else if (!pi.exported) {
6967            return false;
6968        }
6969
6970        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6971        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6972        try {
6973            // check if target holds top-level <provider> permissions
6974            if (!readMet && pi.readPermission != null && considerUidPermissions
6975                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6976                readMet = true;
6977            }
6978            if (!writeMet && pi.writePermission != null && considerUidPermissions
6979                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6980                writeMet = true;
6981            }
6982
6983            // track if unprotected read/write is allowed; any denied
6984            // <path-permission> below removes this ability
6985            boolean allowDefaultRead = pi.readPermission == null;
6986            boolean allowDefaultWrite = pi.writePermission == null;
6987
6988            // check if target holds any <path-permission> that match uri
6989            final PathPermission[] pps = pi.pathPermissions;
6990            if (pps != null) {
6991                final String path = grantUri.uri.getPath();
6992                int i = pps.length;
6993                while (i > 0 && (!readMet || !writeMet)) {
6994                    i--;
6995                    PathPermission pp = pps[i];
6996                    if (pp.match(path)) {
6997                        if (!readMet) {
6998                            final String pprperm = pp.getReadPermission();
6999                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7000                                    + pprperm + " for " + pp.getPath()
7001                                    + ": match=" + pp.match(path)
7002                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7003                            if (pprperm != null) {
7004                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7005                                        == PERMISSION_GRANTED) {
7006                                    readMet = true;
7007                                } else {
7008                                    allowDefaultRead = false;
7009                                }
7010                            }
7011                        }
7012                        if (!writeMet) {
7013                            final String ppwperm = pp.getWritePermission();
7014                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7015                                    + ppwperm + " for " + pp.getPath()
7016                                    + ": match=" + pp.match(path)
7017                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7018                            if (ppwperm != null) {
7019                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7020                                        == PERMISSION_GRANTED) {
7021                                    writeMet = true;
7022                                } else {
7023                                    allowDefaultWrite = false;
7024                                }
7025                            }
7026                        }
7027                    }
7028                }
7029            }
7030
7031            // grant unprotected <provider> read/write, if not blocked by
7032            // <path-permission> above
7033            if (allowDefaultRead) readMet = true;
7034            if (allowDefaultWrite) writeMet = true;
7035
7036        } catch (RemoteException e) {
7037            return false;
7038        }
7039
7040        return readMet && writeMet;
7041    }
7042
7043    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7044        ProviderInfo pi = null;
7045        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7046        if (cpr != null) {
7047            pi = cpr.info;
7048        } else {
7049            try {
7050                pi = AppGlobals.getPackageManager().resolveContentProvider(
7051                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7052            } catch (RemoteException ex) {
7053            }
7054        }
7055        return pi;
7056    }
7057
7058    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7059        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7060        if (targetUris != null) {
7061            return targetUris.get(grantUri);
7062        }
7063        return null;
7064    }
7065
7066    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7067            String targetPkg, int targetUid, GrantUri grantUri) {
7068        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7069        if (targetUris == null) {
7070            targetUris = Maps.newArrayMap();
7071            mGrantedUriPermissions.put(targetUid, targetUris);
7072        }
7073
7074        UriPermission perm = targetUris.get(grantUri);
7075        if (perm == null) {
7076            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7077            targetUris.put(grantUri, perm);
7078        }
7079
7080        return perm;
7081    }
7082
7083    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7084            final int modeFlags) {
7085        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7086        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7087                : UriPermission.STRENGTH_OWNED;
7088
7089        // Root gets to do everything.
7090        if (uid == 0) {
7091            return true;
7092        }
7093
7094        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7095        if (perms == null) return false;
7096
7097        // First look for exact match
7098        final UriPermission exactPerm = perms.get(grantUri);
7099        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7100            return true;
7101        }
7102
7103        // No exact match, look for prefixes
7104        final int N = perms.size();
7105        for (int i = 0; i < N; i++) {
7106            final UriPermission perm = perms.valueAt(i);
7107            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7108                    && perm.getStrength(modeFlags) >= minStrength) {
7109                return true;
7110            }
7111        }
7112
7113        return false;
7114    }
7115
7116    /**
7117     * @param uri This uri must NOT contain an embedded userId.
7118     * @param userId The userId in which the uri is to be resolved.
7119     */
7120    @Override
7121    public int checkUriPermission(Uri uri, int pid, int uid,
7122            final int modeFlags, int userId) {
7123        enforceNotIsolatedCaller("checkUriPermission");
7124
7125        // Another redirected-binder-call permissions check as in
7126        // {@link checkComponentPermission}.
7127        Identity tlsIdentity = sCallerIdentity.get();
7128        if (tlsIdentity != null) {
7129            uid = tlsIdentity.uid;
7130            pid = tlsIdentity.pid;
7131        }
7132
7133        // Our own process gets to do everything.
7134        if (pid == MY_PID) {
7135            return PackageManager.PERMISSION_GRANTED;
7136        }
7137        synchronized (this) {
7138            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7139                    ? PackageManager.PERMISSION_GRANTED
7140                    : PackageManager.PERMISSION_DENIED;
7141        }
7142    }
7143
7144    /**
7145     * Check if the targetPkg can be granted permission to access uri by
7146     * the callingUid using the given modeFlags.  Throws a security exception
7147     * if callingUid is not allowed to do this.  Returns the uid of the target
7148     * if the URI permission grant should be performed; returns -1 if it is not
7149     * needed (for example targetPkg already has permission to access the URI).
7150     * If you already know the uid of the target, you can supply it in
7151     * lastTargetUid else set that to -1.
7152     */
7153    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7154            final int modeFlags, int lastTargetUid) {
7155        if (!Intent.isAccessUriMode(modeFlags)) {
7156            return -1;
7157        }
7158
7159        if (targetPkg != null) {
7160            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7161                    "Checking grant " + targetPkg + " permission to " + grantUri);
7162        }
7163
7164        final IPackageManager pm = AppGlobals.getPackageManager();
7165
7166        // If this is not a content: uri, we can't do anything with it.
7167        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7168            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7169                    "Can't grant URI permission for non-content URI: " + grantUri);
7170            return -1;
7171        }
7172
7173        final String authority = grantUri.uri.getAuthority();
7174        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7175        if (pi == null) {
7176            Slog.w(TAG, "No content provider found for permission check: " +
7177                    grantUri.uri.toSafeString());
7178            return -1;
7179        }
7180
7181        int targetUid = lastTargetUid;
7182        if (targetUid < 0 && targetPkg != null) {
7183            try {
7184                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7185                if (targetUid < 0) {
7186                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7187                            "Can't grant URI permission no uid for: " + targetPkg);
7188                    return -1;
7189                }
7190            } catch (RemoteException ex) {
7191                return -1;
7192            }
7193        }
7194
7195        if (targetUid >= 0) {
7196            // First...  does the target actually need this permission?
7197            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7198                // No need to grant the target this permission.
7199                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7200                        "Target " + targetPkg + " already has full permission to " + grantUri);
7201                return -1;
7202            }
7203        } else {
7204            // First...  there is no target package, so can anyone access it?
7205            boolean allowed = pi.exported;
7206            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7207                if (pi.readPermission != null) {
7208                    allowed = false;
7209                }
7210            }
7211            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7212                if (pi.writePermission != null) {
7213                    allowed = false;
7214                }
7215            }
7216            if (allowed) {
7217                return -1;
7218            }
7219        }
7220
7221        /* There is a special cross user grant if:
7222         * - The target is on another user.
7223         * - Apps on the current user can access the uri without any uid permissions.
7224         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7225         * grant uri permissions.
7226         */
7227        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7228                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7229                modeFlags, false /*without considering the uid permissions*/);
7230
7231        // Second...  is the provider allowing granting of URI permissions?
7232        if (!specialCrossUserGrant) {
7233            if (!pi.grantUriPermissions) {
7234                throw new SecurityException("Provider " + pi.packageName
7235                        + "/" + pi.name
7236                        + " does not allow granting of Uri permissions (uri "
7237                        + grantUri + ")");
7238            }
7239            if (pi.uriPermissionPatterns != null) {
7240                final int N = pi.uriPermissionPatterns.length;
7241                boolean allowed = false;
7242                for (int i=0; i<N; i++) {
7243                    if (pi.uriPermissionPatterns[i] != null
7244                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7245                        allowed = true;
7246                        break;
7247                    }
7248                }
7249                if (!allowed) {
7250                    throw new SecurityException("Provider " + pi.packageName
7251                            + "/" + pi.name
7252                            + " does not allow granting of permission to path of Uri "
7253                            + grantUri);
7254                }
7255            }
7256        }
7257
7258        // Third...  does the caller itself have permission to access
7259        // this uri?
7260        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7261            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7262                // Require they hold a strong enough Uri permission
7263                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7264                    throw new SecurityException("Uid " + callingUid
7265                            + " does not have permission to uri " + grantUri);
7266                }
7267            }
7268        }
7269        return targetUid;
7270    }
7271
7272    /**
7273     * @param uri This uri must NOT contain an embedded userId.
7274     * @param userId The userId in which the uri is to be resolved.
7275     */
7276    @Override
7277    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7278            final int modeFlags, int userId) {
7279        enforceNotIsolatedCaller("checkGrantUriPermission");
7280        synchronized(this) {
7281            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7282                    new GrantUri(userId, uri, false), modeFlags, -1);
7283        }
7284    }
7285
7286    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7287            final int modeFlags, UriPermissionOwner owner) {
7288        if (!Intent.isAccessUriMode(modeFlags)) {
7289            return;
7290        }
7291
7292        // So here we are: the caller has the assumed permission
7293        // to the uri, and the target doesn't.  Let's now give this to
7294        // the target.
7295
7296        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7297                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7298
7299        final String authority = grantUri.uri.getAuthority();
7300        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7301        if (pi == null) {
7302            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7303            return;
7304        }
7305
7306        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7307            grantUri.prefix = true;
7308        }
7309        final UriPermission perm = findOrCreateUriPermissionLocked(
7310                pi.packageName, targetPkg, targetUid, grantUri);
7311        perm.grantModes(modeFlags, owner);
7312    }
7313
7314    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7315            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7316        if (targetPkg == null) {
7317            throw new NullPointerException("targetPkg");
7318        }
7319        int targetUid;
7320        final IPackageManager pm = AppGlobals.getPackageManager();
7321        try {
7322            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7323        } catch (RemoteException ex) {
7324            return;
7325        }
7326
7327        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7328                targetUid);
7329        if (targetUid < 0) {
7330            return;
7331        }
7332
7333        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7334                owner);
7335    }
7336
7337    static class NeededUriGrants extends ArrayList<GrantUri> {
7338        final String targetPkg;
7339        final int targetUid;
7340        final int flags;
7341
7342        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7343            this.targetPkg = targetPkg;
7344            this.targetUid = targetUid;
7345            this.flags = flags;
7346        }
7347    }
7348
7349    /**
7350     * Like checkGrantUriPermissionLocked, but takes an Intent.
7351     */
7352    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7353            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7354        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7355                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7356                + " clip=" + (intent != null ? intent.getClipData() : null)
7357                + " from " + intent + "; flags=0x"
7358                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7359
7360        if (targetPkg == null) {
7361            throw new NullPointerException("targetPkg");
7362        }
7363
7364        if (intent == null) {
7365            return null;
7366        }
7367        Uri data = intent.getData();
7368        ClipData clip = intent.getClipData();
7369        if (data == null && clip == null) {
7370            return null;
7371        }
7372        // Default userId for uris in the intent (if they don't specify it themselves)
7373        int contentUserHint = intent.getContentUserHint();
7374        if (contentUserHint == UserHandle.USER_CURRENT) {
7375            contentUserHint = UserHandle.getUserId(callingUid);
7376        }
7377        final IPackageManager pm = AppGlobals.getPackageManager();
7378        int targetUid;
7379        if (needed != null) {
7380            targetUid = needed.targetUid;
7381        } else {
7382            try {
7383                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7384            } catch (RemoteException ex) {
7385                return null;
7386            }
7387            if (targetUid < 0) {
7388                if (DEBUG_URI_PERMISSION) {
7389                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7390                            + " on user " + targetUserId);
7391                }
7392                return null;
7393            }
7394        }
7395        if (data != null) {
7396            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7397            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7398                    targetUid);
7399            if (targetUid > 0) {
7400                if (needed == null) {
7401                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7402                }
7403                needed.add(grantUri);
7404            }
7405        }
7406        if (clip != null) {
7407            for (int i=0; i<clip.getItemCount(); i++) {
7408                Uri uri = clip.getItemAt(i).getUri();
7409                if (uri != null) {
7410                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7411                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7412                            targetUid);
7413                    if (targetUid > 0) {
7414                        if (needed == null) {
7415                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7416                        }
7417                        needed.add(grantUri);
7418                    }
7419                } else {
7420                    Intent clipIntent = clip.getItemAt(i).getIntent();
7421                    if (clipIntent != null) {
7422                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7423                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7424                        if (newNeeded != null) {
7425                            needed = newNeeded;
7426                        }
7427                    }
7428                }
7429            }
7430        }
7431
7432        return needed;
7433    }
7434
7435    /**
7436     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7437     */
7438    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7439            UriPermissionOwner owner) {
7440        if (needed != null) {
7441            for (int i=0; i<needed.size(); i++) {
7442                GrantUri grantUri = needed.get(i);
7443                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7444                        grantUri, needed.flags, owner);
7445            }
7446        }
7447    }
7448
7449    void grantUriPermissionFromIntentLocked(int callingUid,
7450            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7451        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7452                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7453        if (needed == null) {
7454            return;
7455        }
7456
7457        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7458    }
7459
7460    /**
7461     * @param uri This uri must NOT contain an embedded userId.
7462     * @param userId The userId in which the uri is to be resolved.
7463     */
7464    @Override
7465    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7466            final int modeFlags, int userId) {
7467        enforceNotIsolatedCaller("grantUriPermission");
7468        GrantUri grantUri = new GrantUri(userId, uri, false);
7469        synchronized(this) {
7470            final ProcessRecord r = getRecordForAppLocked(caller);
7471            if (r == null) {
7472                throw new SecurityException("Unable to find app for caller "
7473                        + caller
7474                        + " when granting permission to uri " + grantUri);
7475            }
7476            if (targetPkg == null) {
7477                throw new IllegalArgumentException("null target");
7478            }
7479            if (grantUri == null) {
7480                throw new IllegalArgumentException("null uri");
7481            }
7482
7483            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7484                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7485                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7486                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7487
7488            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7489                    UserHandle.getUserId(r.uid));
7490        }
7491    }
7492
7493    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7494        if (perm.modeFlags == 0) {
7495            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7496                    perm.targetUid);
7497            if (perms != null) {
7498                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7499                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7500
7501                perms.remove(perm.uri);
7502                if (perms.isEmpty()) {
7503                    mGrantedUriPermissions.remove(perm.targetUid);
7504                }
7505            }
7506        }
7507    }
7508
7509    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7510        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7511
7512        final IPackageManager pm = AppGlobals.getPackageManager();
7513        final String authority = grantUri.uri.getAuthority();
7514        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7515        if (pi == null) {
7516            Slog.w(TAG, "No content provider found for permission revoke: "
7517                    + grantUri.toSafeString());
7518            return;
7519        }
7520
7521        // Does the caller have this permission on the URI?
7522        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7523            // Have they don't have direct access to the URI, then revoke any URI
7524            // permissions that have been granted to them.
7525            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7526            if (perms != null) {
7527                boolean persistChanged = false;
7528                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7529                    final UriPermission perm = it.next();
7530                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7531                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7532                        if (DEBUG_URI_PERMISSION)
7533                            Slog.v(TAG,
7534                                    "Revoking " + perm.targetUid + " permission to " + perm.uri);
7535                        persistChanged |= perm.revokeModes(
7536                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7537                        if (perm.modeFlags == 0) {
7538                            it.remove();
7539                        }
7540                    }
7541                }
7542                if (perms.isEmpty()) {
7543                    mGrantedUriPermissions.remove(callingUid);
7544                }
7545                if (persistChanged) {
7546                    schedulePersistUriGrants();
7547                }
7548            }
7549            return;
7550        }
7551
7552        boolean persistChanged = false;
7553
7554        // Go through all of the permissions and remove any that match.
7555        int N = mGrantedUriPermissions.size();
7556        for (int i = 0; i < N; i++) {
7557            final int targetUid = mGrantedUriPermissions.keyAt(i);
7558            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7559
7560            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7561                final UriPermission perm = it.next();
7562                if (perm.uri.sourceUserId == grantUri.sourceUserId
7563                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7564                    if (DEBUG_URI_PERMISSION)
7565                        Slog.v(TAG,
7566                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7567                    persistChanged |= perm.revokeModes(
7568                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7569                    if (perm.modeFlags == 0) {
7570                        it.remove();
7571                    }
7572                }
7573            }
7574
7575            if (perms.isEmpty()) {
7576                mGrantedUriPermissions.remove(targetUid);
7577                N--;
7578                i--;
7579            }
7580        }
7581
7582        if (persistChanged) {
7583            schedulePersistUriGrants();
7584        }
7585    }
7586
7587    /**
7588     * @param uri This uri must NOT contain an embedded userId.
7589     * @param userId The userId in which the uri is to be resolved.
7590     */
7591    @Override
7592    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7593            int userId) {
7594        enforceNotIsolatedCaller("revokeUriPermission");
7595        synchronized(this) {
7596            final ProcessRecord r = getRecordForAppLocked(caller);
7597            if (r == null) {
7598                throw new SecurityException("Unable to find app for caller "
7599                        + caller
7600                        + " when revoking permission to uri " + uri);
7601            }
7602            if (uri == null) {
7603                Slog.w(TAG, "revokeUriPermission: null uri");
7604                return;
7605            }
7606
7607            if (!Intent.isAccessUriMode(modeFlags)) {
7608                return;
7609            }
7610
7611            final IPackageManager pm = AppGlobals.getPackageManager();
7612            final String authority = uri.getAuthority();
7613            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7614            if (pi == null) {
7615                Slog.w(TAG, "No content provider found for permission revoke: "
7616                        + uri.toSafeString());
7617                return;
7618            }
7619
7620            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7621        }
7622    }
7623
7624    /**
7625     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7626     * given package.
7627     *
7628     * @param packageName Package name to match, or {@code null} to apply to all
7629     *            packages.
7630     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7631     *            to all users.
7632     * @param persistable If persistable grants should be removed.
7633     */
7634    private void removeUriPermissionsForPackageLocked(
7635            String packageName, int userHandle, boolean persistable) {
7636        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7637            throw new IllegalArgumentException("Must narrow by either package or user");
7638        }
7639
7640        boolean persistChanged = false;
7641
7642        int N = mGrantedUriPermissions.size();
7643        for (int i = 0; i < N; i++) {
7644            final int targetUid = mGrantedUriPermissions.keyAt(i);
7645            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7646
7647            // Only inspect grants matching user
7648            if (userHandle == UserHandle.USER_ALL
7649                    || userHandle == UserHandle.getUserId(targetUid)) {
7650                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7651                    final UriPermission perm = it.next();
7652
7653                    // Only inspect grants matching package
7654                    if (packageName == null || perm.sourcePkg.equals(packageName)
7655                            || perm.targetPkg.equals(packageName)) {
7656                        persistChanged |= perm.revokeModes(
7657                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7658
7659                        // Only remove when no modes remain; any persisted grants
7660                        // will keep this alive.
7661                        if (perm.modeFlags == 0) {
7662                            it.remove();
7663                        }
7664                    }
7665                }
7666
7667                if (perms.isEmpty()) {
7668                    mGrantedUriPermissions.remove(targetUid);
7669                    N--;
7670                    i--;
7671                }
7672            }
7673        }
7674
7675        if (persistChanged) {
7676            schedulePersistUriGrants();
7677        }
7678    }
7679
7680    @Override
7681    public IBinder newUriPermissionOwner(String name) {
7682        enforceNotIsolatedCaller("newUriPermissionOwner");
7683        synchronized(this) {
7684            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7685            return owner.getExternalTokenLocked();
7686        }
7687    }
7688
7689    /**
7690     * @param uri This uri must NOT contain an embedded userId.
7691     * @param sourceUserId The userId in which the uri is to be resolved.
7692     * @param targetUserId The userId of the app that receives the grant.
7693     */
7694    @Override
7695    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7696            final int modeFlags, int sourceUserId, int targetUserId) {
7697        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7698                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7699        synchronized(this) {
7700            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7701            if (owner == null) {
7702                throw new IllegalArgumentException("Unknown owner: " + token);
7703            }
7704            if (fromUid != Binder.getCallingUid()) {
7705                if (Binder.getCallingUid() != Process.myUid()) {
7706                    // Only system code can grant URI permissions on behalf
7707                    // of other users.
7708                    throw new SecurityException("nice try");
7709                }
7710            }
7711            if (targetPkg == null) {
7712                throw new IllegalArgumentException("null target");
7713            }
7714            if (uri == null) {
7715                throw new IllegalArgumentException("null uri");
7716            }
7717
7718            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7719                    modeFlags, owner, targetUserId);
7720        }
7721    }
7722
7723    /**
7724     * @param uri This uri must NOT contain an embedded userId.
7725     * @param userId The userId in which the uri is to be resolved.
7726     */
7727    @Override
7728    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7729        synchronized(this) {
7730            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7731            if (owner == null) {
7732                throw new IllegalArgumentException("Unknown owner: " + token);
7733            }
7734
7735            if (uri == null) {
7736                owner.removeUriPermissionsLocked(mode);
7737            } else {
7738                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7739            }
7740        }
7741    }
7742
7743    private void schedulePersistUriGrants() {
7744        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7745            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7746                    10 * DateUtils.SECOND_IN_MILLIS);
7747        }
7748    }
7749
7750    private void writeGrantedUriPermissions() {
7751        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7752
7753        // Snapshot permissions so we can persist without lock
7754        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7755        synchronized (this) {
7756            final int size = mGrantedUriPermissions.size();
7757            for (int i = 0; i < size; i++) {
7758                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7759                for (UriPermission perm : perms.values()) {
7760                    if (perm.persistedModeFlags != 0) {
7761                        persist.add(perm.snapshot());
7762                    }
7763                }
7764            }
7765        }
7766
7767        FileOutputStream fos = null;
7768        try {
7769            fos = mGrantFile.startWrite();
7770
7771            XmlSerializer out = new FastXmlSerializer();
7772            out.setOutput(fos, "utf-8");
7773            out.startDocument(null, true);
7774            out.startTag(null, TAG_URI_GRANTS);
7775            for (UriPermission.Snapshot perm : persist) {
7776                out.startTag(null, TAG_URI_GRANT);
7777                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7778                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7779                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7780                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7781                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7782                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7783                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7784                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7785                out.endTag(null, TAG_URI_GRANT);
7786            }
7787            out.endTag(null, TAG_URI_GRANTS);
7788            out.endDocument();
7789
7790            mGrantFile.finishWrite(fos);
7791        } catch (IOException e) {
7792            if (fos != null) {
7793                mGrantFile.failWrite(fos);
7794            }
7795        }
7796    }
7797
7798    private void readGrantedUriPermissionsLocked() {
7799        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7800
7801        final long now = System.currentTimeMillis();
7802
7803        FileInputStream fis = null;
7804        try {
7805            fis = mGrantFile.openRead();
7806            final XmlPullParser in = Xml.newPullParser();
7807            in.setInput(fis, null);
7808
7809            int type;
7810            while ((type = in.next()) != END_DOCUMENT) {
7811                final String tag = in.getName();
7812                if (type == START_TAG) {
7813                    if (TAG_URI_GRANT.equals(tag)) {
7814                        final int sourceUserId;
7815                        final int targetUserId;
7816                        final int userHandle = readIntAttribute(in,
7817                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7818                        if (userHandle != UserHandle.USER_NULL) {
7819                            // For backwards compatibility.
7820                            sourceUserId = userHandle;
7821                            targetUserId = userHandle;
7822                        } else {
7823                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7824                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7825                        }
7826                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7827                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7828                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7829                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7830                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7831                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7832
7833                        // Sanity check that provider still belongs to source package
7834                        final ProviderInfo pi = getProviderInfoLocked(
7835                                uri.getAuthority(), sourceUserId);
7836                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7837                            int targetUid = -1;
7838                            try {
7839                                targetUid = AppGlobals.getPackageManager()
7840                                        .getPackageUid(targetPkg, targetUserId);
7841                            } catch (RemoteException e) {
7842                            }
7843                            if (targetUid != -1) {
7844                                final UriPermission perm = findOrCreateUriPermissionLocked(
7845                                        sourcePkg, targetPkg, targetUid,
7846                                        new GrantUri(sourceUserId, uri, prefix));
7847                                perm.initPersistedModes(modeFlags, createdTime);
7848                            }
7849                        } else {
7850                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7851                                    + " but instead found " + pi);
7852                        }
7853                    }
7854                }
7855            }
7856        } catch (FileNotFoundException e) {
7857            // Missing grants is okay
7858        } catch (IOException e) {
7859            Log.wtf(TAG, "Failed reading Uri grants", e);
7860        } catch (XmlPullParserException e) {
7861            Log.wtf(TAG, "Failed reading Uri grants", e);
7862        } finally {
7863            IoUtils.closeQuietly(fis);
7864        }
7865    }
7866
7867    /**
7868     * @param uri This uri must NOT contain an embedded userId.
7869     * @param userId The userId in which the uri is to be resolved.
7870     */
7871    @Override
7872    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7873        enforceNotIsolatedCaller("takePersistableUriPermission");
7874
7875        Preconditions.checkFlagsArgument(modeFlags,
7876                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7877
7878        synchronized (this) {
7879            final int callingUid = Binder.getCallingUid();
7880            boolean persistChanged = false;
7881            GrantUri grantUri = new GrantUri(userId, uri, false);
7882
7883            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7884                    new GrantUri(userId, uri, false));
7885            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7886                    new GrantUri(userId, uri, true));
7887
7888            final boolean exactValid = (exactPerm != null)
7889                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7890            final boolean prefixValid = (prefixPerm != null)
7891                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7892
7893            if (!(exactValid || prefixValid)) {
7894                throw new SecurityException("No persistable permission grants found for UID "
7895                        + callingUid + " and Uri " + grantUri.toSafeString());
7896            }
7897
7898            if (exactValid) {
7899                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7900            }
7901            if (prefixValid) {
7902                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7903            }
7904
7905            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7906
7907            if (persistChanged) {
7908                schedulePersistUriGrants();
7909            }
7910        }
7911    }
7912
7913    /**
7914     * @param uri This uri must NOT contain an embedded userId.
7915     * @param userId The userId in which the uri is to be resolved.
7916     */
7917    @Override
7918    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7919        enforceNotIsolatedCaller("releasePersistableUriPermission");
7920
7921        Preconditions.checkFlagsArgument(modeFlags,
7922                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7923
7924        synchronized (this) {
7925            final int callingUid = Binder.getCallingUid();
7926            boolean persistChanged = false;
7927
7928            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7929                    new GrantUri(userId, uri, false));
7930            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7931                    new GrantUri(userId, uri, true));
7932            if (exactPerm == null && prefixPerm == null) {
7933                throw new SecurityException("No permission grants found for UID " + callingUid
7934                        + " and Uri " + uri.toSafeString());
7935            }
7936
7937            if (exactPerm != null) {
7938                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7939                removeUriPermissionIfNeededLocked(exactPerm);
7940            }
7941            if (prefixPerm != null) {
7942                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7943                removeUriPermissionIfNeededLocked(prefixPerm);
7944            }
7945
7946            if (persistChanged) {
7947                schedulePersistUriGrants();
7948            }
7949        }
7950    }
7951
7952    /**
7953     * Prune any older {@link UriPermission} for the given UID until outstanding
7954     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7955     *
7956     * @return if any mutations occured that require persisting.
7957     */
7958    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7959        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7960        if (perms == null) return false;
7961        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7962
7963        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7964        for (UriPermission perm : perms.values()) {
7965            if (perm.persistedModeFlags != 0) {
7966                persisted.add(perm);
7967            }
7968        }
7969
7970        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7971        if (trimCount <= 0) return false;
7972
7973        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7974        for (int i = 0; i < trimCount; i++) {
7975            final UriPermission perm = persisted.get(i);
7976
7977            if (DEBUG_URI_PERMISSION) {
7978                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7979            }
7980
7981            perm.releasePersistableModes(~0);
7982            removeUriPermissionIfNeededLocked(perm);
7983        }
7984
7985        return true;
7986    }
7987
7988    @Override
7989    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7990            String packageName, boolean incoming) {
7991        enforceNotIsolatedCaller("getPersistedUriPermissions");
7992        Preconditions.checkNotNull(packageName, "packageName");
7993
7994        final int callingUid = Binder.getCallingUid();
7995        final IPackageManager pm = AppGlobals.getPackageManager();
7996        try {
7997            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7998            if (packageUid != callingUid) {
7999                throw new SecurityException(
8000                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8001            }
8002        } catch (RemoteException e) {
8003            throw new SecurityException("Failed to verify package name ownership");
8004        }
8005
8006        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8007        synchronized (this) {
8008            if (incoming) {
8009                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8010                        callingUid);
8011                if (perms == null) {
8012                    Slog.w(TAG, "No permission grants found for " + packageName);
8013                } else {
8014                    for (UriPermission perm : perms.values()) {
8015                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8016                            result.add(perm.buildPersistedPublicApiObject());
8017                        }
8018                    }
8019                }
8020            } else {
8021                final int size = mGrantedUriPermissions.size();
8022                for (int i = 0; i < size; i++) {
8023                    final ArrayMap<GrantUri, UriPermission> perms =
8024                            mGrantedUriPermissions.valueAt(i);
8025                    for (UriPermission perm : perms.values()) {
8026                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8027                            result.add(perm.buildPersistedPublicApiObject());
8028                        }
8029                    }
8030                }
8031            }
8032        }
8033        return new ParceledListSlice<android.content.UriPermission>(result);
8034    }
8035
8036    @Override
8037    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8038        synchronized (this) {
8039            ProcessRecord app =
8040                who != null ? getRecordForAppLocked(who) : null;
8041            if (app == null) return;
8042
8043            Message msg = Message.obtain();
8044            msg.what = WAIT_FOR_DEBUGGER_MSG;
8045            msg.obj = app;
8046            msg.arg1 = waiting ? 1 : 0;
8047            mHandler.sendMessage(msg);
8048        }
8049    }
8050
8051    @Override
8052    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8053        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8054        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8055        outInfo.availMem = Process.getFreeMemory();
8056        outInfo.totalMem = Process.getTotalMemory();
8057        outInfo.threshold = homeAppMem;
8058        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8059        outInfo.hiddenAppThreshold = cachedAppMem;
8060        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8061                ProcessList.SERVICE_ADJ);
8062        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8063                ProcessList.VISIBLE_APP_ADJ);
8064        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8065                ProcessList.FOREGROUND_APP_ADJ);
8066    }
8067
8068    // =========================================================
8069    // TASK MANAGEMENT
8070    // =========================================================
8071
8072    @Override
8073    public List<IAppTask> getAppTasks(String callingPackage) {
8074        int callingUid = Binder.getCallingUid();
8075        long ident = Binder.clearCallingIdentity();
8076
8077        synchronized(this) {
8078            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8079            try {
8080                if (localLOGV) Slog.v(TAG, "getAppTasks");
8081
8082                final int N = mRecentTasks.size();
8083                for (int i = 0; i < N; i++) {
8084                    TaskRecord tr = mRecentTasks.get(i);
8085                    // Skip tasks that do not match the caller.  We don't need to verify
8086                    // callingPackage, because we are also limiting to callingUid and know
8087                    // that will limit to the correct security sandbox.
8088                    if (tr.effectiveUid != callingUid) {
8089                        continue;
8090                    }
8091                    Intent intent = tr.getBaseIntent();
8092                    if (intent == null ||
8093                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8094                        continue;
8095                    }
8096                    ActivityManager.RecentTaskInfo taskInfo =
8097                            createRecentTaskInfoFromTaskRecord(tr);
8098                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8099                    list.add(taskImpl);
8100                }
8101            } finally {
8102                Binder.restoreCallingIdentity(ident);
8103            }
8104            return list;
8105        }
8106    }
8107
8108    @Override
8109    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8110        final int callingUid = Binder.getCallingUid();
8111        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8112
8113        synchronized(this) {
8114            if (localLOGV) Slog.v(
8115                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8116
8117            final boolean allowed = checkCallingPermission(
8118                    android.Manifest.permission.GET_TASKS)
8119                    == PackageManager.PERMISSION_GRANTED;
8120            if (!allowed) {
8121                Slog.w(TAG, "getTasks: caller " + callingUid
8122                        + " does not hold GET_TASKS; limiting output");
8123            }
8124
8125            // TODO: Improve with MRU list from all ActivityStacks.
8126            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8127        }
8128
8129        return list;
8130    }
8131
8132    TaskRecord getMostRecentTask() {
8133        return mRecentTasks.get(0);
8134    }
8135
8136    /**
8137     * Creates a new RecentTaskInfo from a TaskRecord.
8138     */
8139    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8140        // Update the task description to reflect any changes in the task stack
8141        tr.updateTaskDescription();
8142
8143        // Compose the recent task info
8144        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8145        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8146        rti.persistentId = tr.taskId;
8147        rti.baseIntent = new Intent(tr.getBaseIntent());
8148        rti.origActivity = tr.origActivity;
8149        rti.description = tr.lastDescription;
8150        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8151        rti.userId = tr.userId;
8152        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8153        rti.firstActiveTime = tr.firstActiveTime;
8154        rti.lastActiveTime = tr.lastActiveTime;
8155        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8156        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8157        return rti;
8158    }
8159
8160    @Override
8161    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8162        final int callingUid = Binder.getCallingUid();
8163        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8164                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8165
8166        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8167        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8168        synchronized (this) {
8169            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8170                    == PackageManager.PERMISSION_GRANTED;
8171            if (!allowed) {
8172                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8173                        + " does not hold GET_TASKS; limiting output");
8174            }
8175            final boolean detailed = checkCallingPermission(
8176                    android.Manifest.permission.GET_DETAILED_TASKS)
8177                    == PackageManager.PERMISSION_GRANTED;
8178
8179            final int N = mRecentTasks.size();
8180            ArrayList<ActivityManager.RecentTaskInfo> res
8181                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8182                            maxNum < N ? maxNum : N);
8183
8184            final Set<Integer> includedUsers;
8185            if (includeProfiles) {
8186                includedUsers = getProfileIdsLocked(userId);
8187            } else {
8188                includedUsers = new HashSet<Integer>();
8189            }
8190            includedUsers.add(Integer.valueOf(userId));
8191
8192            for (int i=0; i<N && maxNum > 0; i++) {
8193                TaskRecord tr = mRecentTasks.get(i);
8194                // Only add calling user or related users recent tasks
8195                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8196                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8197                    continue;
8198                }
8199
8200                // Return the entry if desired by the caller.  We always return
8201                // the first entry, because callers always expect this to be the
8202                // foreground app.  We may filter others if the caller has
8203                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8204                // we should exclude the entry.
8205
8206                if (i == 0
8207                        || withExcluded
8208                        || (tr.intent == null)
8209                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8210                                == 0)) {
8211                    if (!allowed) {
8212                        // If the caller doesn't have the GET_TASKS permission, then only
8213                        // allow them to see a small subset of tasks -- their own and home.
8214                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8215                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8216                            continue;
8217                        }
8218                    }
8219                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8220                        if (tr.stack != null && tr.stack.isHomeStack()) {
8221                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8222                            continue;
8223                        }
8224                    }
8225                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8226                        // Don't include auto remove tasks that are finished or finishing.
8227                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8228                                + tr);
8229                        continue;
8230                    }
8231                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8232                            && !tr.isAvailable) {
8233                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8234                        continue;
8235                    }
8236
8237                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8238                    if (!detailed) {
8239                        rti.baseIntent.replaceExtras((Bundle)null);
8240                    }
8241
8242                    res.add(rti);
8243                    maxNum--;
8244                }
8245            }
8246            return res;
8247        }
8248    }
8249
8250    private TaskRecord recentTaskForIdLocked(int id) {
8251        final int N = mRecentTasks.size();
8252            for (int i=0; i<N; i++) {
8253                TaskRecord tr = mRecentTasks.get(i);
8254                if (tr.taskId == id) {
8255                    return tr;
8256                }
8257            }
8258            return null;
8259    }
8260
8261    @Override
8262    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8263        synchronized (this) {
8264            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8265                    "getTaskThumbnail()");
8266            TaskRecord tr = recentTaskForIdLocked(id);
8267            if (tr != null) {
8268                return tr.getTaskThumbnailLocked();
8269            }
8270        }
8271        return null;
8272    }
8273
8274    @Override
8275    public int addAppTask(IBinder activityToken, Intent intent,
8276            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8277        final int callingUid = Binder.getCallingUid();
8278        final long callingIdent = Binder.clearCallingIdentity();
8279
8280        try {
8281            synchronized (this) {
8282                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8283                if (r == null) {
8284                    throw new IllegalArgumentException("Activity does not exist; token="
8285                            + activityToken);
8286                }
8287                ComponentName comp = intent.getComponent();
8288                if (comp == null) {
8289                    throw new IllegalArgumentException("Intent " + intent
8290                            + " must specify explicit component");
8291                }
8292                if (thumbnail.getWidth() != mThumbnailWidth
8293                        || thumbnail.getHeight() != mThumbnailHeight) {
8294                    throw new IllegalArgumentException("Bad thumbnail size: got "
8295                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8296                            + mThumbnailWidth + "x" + mThumbnailHeight);
8297                }
8298                if (intent.getSelector() != null) {
8299                    intent.setSelector(null);
8300                }
8301                if (intent.getSourceBounds() != null) {
8302                    intent.setSourceBounds(null);
8303                }
8304                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8305                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8306                        // The caller has added this as an auto-remove task...  that makes no
8307                        // sense, so turn off auto-remove.
8308                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8309                    }
8310                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8311                    // Must be a new task.
8312                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8313                }
8314                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8315                    mLastAddedTaskActivity = null;
8316                }
8317                ActivityInfo ainfo = mLastAddedTaskActivity;
8318                if (ainfo == null) {
8319                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8320                            comp, 0, UserHandle.getUserId(callingUid));
8321                    if (ainfo.applicationInfo.uid != callingUid) {
8322                        throw new SecurityException(
8323                                "Can't add task for another application: target uid="
8324                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8325                    }
8326                }
8327
8328                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8329                        intent, description);
8330
8331                int trimIdx = trimRecentsForTask(task, false);
8332                if (trimIdx >= 0) {
8333                    // If this would have caused a trim, then we'll abort because that
8334                    // means it would be added at the end of the list but then just removed.
8335                    return -1;
8336                }
8337
8338                final int N = mRecentTasks.size();
8339                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8340                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8341                    tr.removedFromRecents(mTaskPersister);
8342                }
8343
8344                task.inRecents = true;
8345                mRecentTasks.add(task);
8346                r.task.stack.addTask(task, false, false);
8347
8348                task.setLastThumbnail(thumbnail);
8349                task.freeLastThumbnail();
8350
8351                return task.taskId;
8352            }
8353        } finally {
8354            Binder.restoreCallingIdentity(callingIdent);
8355        }
8356    }
8357
8358    @Override
8359    public Point getAppTaskThumbnailSize() {
8360        synchronized (this) {
8361            return new Point(mThumbnailWidth,  mThumbnailHeight);
8362        }
8363    }
8364
8365    @Override
8366    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8367        synchronized (this) {
8368            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8369            if (r != null) {
8370                r.taskDescription = td;
8371                r.task.updateTaskDescription();
8372            }
8373        }
8374    }
8375
8376    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8377        mRecentTasks.remove(tr);
8378        tr.removedFromRecents(mTaskPersister);
8379        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8380        Intent baseIntent = new Intent(
8381                tr.intent != null ? tr.intent : tr.affinityIntent);
8382        ComponentName component = baseIntent.getComponent();
8383        if (component == null) {
8384            Slog.w(TAG, "Now component for base intent of task: " + tr);
8385            return;
8386        }
8387
8388        // Find any running services associated with this app.
8389        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8390
8391        if (killProcesses) {
8392            // Find any running processes associated with this app.
8393            final String pkg = component.getPackageName();
8394            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8395            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8396            for (int i=0; i<pmap.size(); i++) {
8397                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8398                for (int j=0; j<uids.size(); j++) {
8399                    ProcessRecord proc = uids.valueAt(j);
8400                    if (proc.userId != tr.userId) {
8401                        continue;
8402                    }
8403                    if (!proc.pkgList.containsKey(pkg)) {
8404                        continue;
8405                    }
8406                    procs.add(proc);
8407                }
8408            }
8409
8410            // Kill the running processes.
8411            for (int i=0; i<procs.size(); i++) {
8412                ProcessRecord pr = procs.get(i);
8413                if (pr == mHomeProcess) {
8414                    // Don't kill the home process along with tasks from the same package.
8415                    continue;
8416                }
8417                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8418                    pr.kill("remove task", true);
8419                } else {
8420                    pr.waitingToKill = "remove task";
8421                }
8422            }
8423        }
8424    }
8425
8426    /**
8427     * Removes the task with the specified task id.
8428     *
8429     * @param taskId Identifier of the task to be removed.
8430     * @param flags Additional operational flags.  May be 0 or
8431     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8432     * @return Returns true if the given task was found and removed.
8433     */
8434    private boolean removeTaskByIdLocked(int taskId, int flags) {
8435        TaskRecord tr = recentTaskForIdLocked(taskId);
8436        if (tr != null) {
8437            tr.removeTaskActivitiesLocked();
8438            cleanUpRemovedTaskLocked(tr, flags);
8439            if (tr.isPersistable) {
8440                notifyTaskPersisterLocked(null, true);
8441            }
8442            return true;
8443        }
8444        return false;
8445    }
8446
8447    @Override
8448    public boolean removeTask(int taskId, int flags) {
8449        synchronized (this) {
8450            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8451                    "removeTask()");
8452            long ident = Binder.clearCallingIdentity();
8453            try {
8454                return removeTaskByIdLocked(taskId, flags);
8455            } finally {
8456                Binder.restoreCallingIdentity(ident);
8457            }
8458        }
8459    }
8460
8461    /**
8462     * TODO: Add mController hook
8463     */
8464    @Override
8465    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8466        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8467                "moveTaskToFront()");
8468
8469        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8470        synchronized(this) {
8471            moveTaskToFrontLocked(taskId, flags, options);
8472        }
8473    }
8474
8475    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8476        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8477                Binder.getCallingUid(), "Task to front")) {
8478            ActivityOptions.abort(options);
8479            return;
8480        }
8481        final long origId = Binder.clearCallingIdentity();
8482        try {
8483            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8484            if (task == null) {
8485                return;
8486            }
8487            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8488                mStackSupervisor.showLockTaskToast();
8489                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8490                return;
8491            }
8492            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8493            if (prev != null && prev.isRecentsActivity()) {
8494                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8495            }
8496            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8497        } finally {
8498            Binder.restoreCallingIdentity(origId);
8499        }
8500        ActivityOptions.abort(options);
8501    }
8502
8503    @Override
8504    public void moveTaskToBack(int taskId) {
8505        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8506                "moveTaskToBack()");
8507
8508        synchronized(this) {
8509            TaskRecord tr = recentTaskForIdLocked(taskId);
8510            if (tr != null) {
8511                if (tr == mStackSupervisor.mLockTaskModeTask) {
8512                    mStackSupervisor.showLockTaskToast();
8513                    return;
8514                }
8515                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8516                ActivityStack stack = tr.stack;
8517                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8518                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8519                            Binder.getCallingUid(), "Task to back")) {
8520                        return;
8521                    }
8522                }
8523                final long origId = Binder.clearCallingIdentity();
8524                try {
8525                    stack.moveTaskToBackLocked(taskId, null);
8526                } finally {
8527                    Binder.restoreCallingIdentity(origId);
8528                }
8529            }
8530        }
8531    }
8532
8533    /**
8534     * Moves an activity, and all of the other activities within the same task, to the bottom
8535     * of the history stack.  The activity's order within the task is unchanged.
8536     *
8537     * @param token A reference to the activity we wish to move
8538     * @param nonRoot If false then this only works if the activity is the root
8539     *                of a task; if true it will work for any activity in a task.
8540     * @return Returns true if the move completed, false if not.
8541     */
8542    @Override
8543    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8544        enforceNotIsolatedCaller("moveActivityTaskToBack");
8545        synchronized(this) {
8546            final long origId = Binder.clearCallingIdentity();
8547            try {
8548                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8549                if (taskId >= 0) {
8550                    if ((mStackSupervisor.mLockTaskModeTask != null)
8551                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8552                        mStackSupervisor.showLockTaskToast();
8553                        return false;
8554                    }
8555                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8556                }
8557            } finally {
8558                Binder.restoreCallingIdentity(origId);
8559            }
8560        }
8561        return false;
8562    }
8563
8564    @Override
8565    public void moveTaskBackwards(int task) {
8566        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8567                "moveTaskBackwards()");
8568
8569        synchronized(this) {
8570            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8571                    Binder.getCallingUid(), "Task backwards")) {
8572                return;
8573            }
8574            final long origId = Binder.clearCallingIdentity();
8575            moveTaskBackwardsLocked(task);
8576            Binder.restoreCallingIdentity(origId);
8577        }
8578    }
8579
8580    private final void moveTaskBackwardsLocked(int task) {
8581        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8582    }
8583
8584    @Override
8585    public IBinder getHomeActivityToken() throws RemoteException {
8586        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8587                "getHomeActivityToken()");
8588        synchronized (this) {
8589            return mStackSupervisor.getHomeActivityToken();
8590        }
8591    }
8592
8593    @Override
8594    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8595            IActivityContainerCallback callback) throws RemoteException {
8596        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8597                "createActivityContainer()");
8598        synchronized (this) {
8599            if (parentActivityToken == null) {
8600                throw new IllegalArgumentException("parent token must not be null");
8601            }
8602            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8603            if (r == null) {
8604                return null;
8605            }
8606            if (callback == null) {
8607                throw new IllegalArgumentException("callback must not be null");
8608            }
8609            return mStackSupervisor.createActivityContainer(r, callback);
8610        }
8611    }
8612
8613    @Override
8614    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8615        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8616                "deleteActivityContainer()");
8617        synchronized (this) {
8618            mStackSupervisor.deleteActivityContainer(container);
8619        }
8620    }
8621
8622    @Override
8623    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8624            throws RemoteException {
8625        synchronized (this) {
8626            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8627            if (stack != null) {
8628                return stack.mActivityContainer;
8629            }
8630            return null;
8631        }
8632    }
8633
8634    @Override
8635    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8636        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8637                "moveTaskToStack()");
8638        if (stackId == HOME_STACK_ID) {
8639            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8640                    new RuntimeException("here").fillInStackTrace());
8641        }
8642        synchronized (this) {
8643            long ident = Binder.clearCallingIdentity();
8644            try {
8645                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8646                        + stackId + " toTop=" + toTop);
8647                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8648            } finally {
8649                Binder.restoreCallingIdentity(ident);
8650            }
8651        }
8652    }
8653
8654    @Override
8655    public void resizeStack(int stackBoxId, Rect bounds) {
8656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8657                "resizeStackBox()");
8658        long ident = Binder.clearCallingIdentity();
8659        try {
8660            mWindowManager.resizeStack(stackBoxId, bounds);
8661        } finally {
8662            Binder.restoreCallingIdentity(ident);
8663        }
8664    }
8665
8666    @Override
8667    public List<StackInfo> getAllStackInfos() {
8668        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8669                "getAllStackInfos()");
8670        long ident = Binder.clearCallingIdentity();
8671        try {
8672            synchronized (this) {
8673                return mStackSupervisor.getAllStackInfosLocked();
8674            }
8675        } finally {
8676            Binder.restoreCallingIdentity(ident);
8677        }
8678    }
8679
8680    @Override
8681    public StackInfo getStackInfo(int stackId) {
8682        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8683                "getStackInfo()");
8684        long ident = Binder.clearCallingIdentity();
8685        try {
8686            synchronized (this) {
8687                return mStackSupervisor.getStackInfoLocked(stackId);
8688            }
8689        } finally {
8690            Binder.restoreCallingIdentity(ident);
8691        }
8692    }
8693
8694    @Override
8695    public boolean isInHomeStack(int taskId) {
8696        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8697                "getStackInfo()");
8698        long ident = Binder.clearCallingIdentity();
8699        try {
8700            synchronized (this) {
8701                TaskRecord tr = recentTaskForIdLocked(taskId);
8702                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8703            }
8704        } finally {
8705            Binder.restoreCallingIdentity(ident);
8706        }
8707    }
8708
8709    @Override
8710    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8711        synchronized(this) {
8712            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8713        }
8714    }
8715
8716    private boolean isLockTaskAuthorized(String pkg) {
8717        final DevicePolicyManager dpm = (DevicePolicyManager)
8718                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8719        try {
8720            int uid = mContext.getPackageManager().getPackageUid(pkg,
8721                    Binder.getCallingUserHandle().getIdentifier());
8722            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8723        } catch (NameNotFoundException e) {
8724            return false;
8725        }
8726    }
8727
8728    void startLockTaskMode(TaskRecord task) {
8729        final String pkg;
8730        synchronized (this) {
8731            pkg = task.intent.getComponent().getPackageName();
8732        }
8733        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8734        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8735            final TaskRecord taskRecord = task;
8736            mHandler.post(new Runnable() {
8737                @Override
8738                public void run() {
8739                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8740                }
8741            });
8742            return;
8743        }
8744        long ident = Binder.clearCallingIdentity();
8745        try {
8746            synchronized (this) {
8747                // Since we lost lock on task, make sure it is still there.
8748                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8749                if (task != null) {
8750                    if (!isSystemInitiated
8751                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8752                        throw new IllegalArgumentException("Invalid task, not in foreground");
8753                    }
8754                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8755                }
8756            }
8757        } finally {
8758            Binder.restoreCallingIdentity(ident);
8759        }
8760    }
8761
8762    @Override
8763    public void startLockTaskMode(int taskId) {
8764        final TaskRecord task;
8765        long ident = Binder.clearCallingIdentity();
8766        try {
8767            synchronized (this) {
8768                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8769            }
8770        } finally {
8771            Binder.restoreCallingIdentity(ident);
8772        }
8773        if (task != null) {
8774            startLockTaskMode(task);
8775        }
8776    }
8777
8778    @Override
8779    public void startLockTaskMode(IBinder token) {
8780        final TaskRecord task;
8781        long ident = Binder.clearCallingIdentity();
8782        try {
8783            synchronized (this) {
8784                final ActivityRecord r = ActivityRecord.forToken(token);
8785                if (r == null) {
8786                    return;
8787                }
8788                task = r.task;
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793        if (task != null) {
8794            startLockTaskMode(task);
8795        }
8796    }
8797
8798    @Override
8799    public void startLockTaskModeOnCurrent() throws RemoteException {
8800        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8801                "startLockTaskModeOnCurrent");
8802        ActivityRecord r = null;
8803        synchronized (this) {
8804            r = mStackSupervisor.topRunningActivityLocked();
8805        }
8806        startLockTaskMode(r.task);
8807    }
8808
8809    @Override
8810    public void stopLockTaskMode() {
8811        // Verify that the user matches the package of the intent for the TaskRecord
8812        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8813        // and stopLockTaskMode.
8814        final int callingUid = Binder.getCallingUid();
8815        if (callingUid != Process.SYSTEM_UID) {
8816            try {
8817                String pkg =
8818                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8819                int uid = mContext.getPackageManager().getPackageUid(pkg,
8820                        Binder.getCallingUserHandle().getIdentifier());
8821                if (uid != callingUid) {
8822                    throw new SecurityException("Invalid uid, expected " + uid);
8823                }
8824            } catch (NameNotFoundException e) {
8825                Log.d(TAG, "stopLockTaskMode " + e);
8826                return;
8827            }
8828        }
8829        long ident = Binder.clearCallingIdentity();
8830        try {
8831            Log.d(TAG, "stopLockTaskMode");
8832            // Stop lock task
8833            synchronized (this) {
8834                mStackSupervisor.setLockTaskModeLocked(null, false);
8835            }
8836        } finally {
8837            Binder.restoreCallingIdentity(ident);
8838        }
8839    }
8840
8841    @Override
8842    public void stopLockTaskModeOnCurrent() throws RemoteException {
8843        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8844                "stopLockTaskModeOnCurrent");
8845        long ident = Binder.clearCallingIdentity();
8846        try {
8847            stopLockTaskMode();
8848        } finally {
8849            Binder.restoreCallingIdentity(ident);
8850        }
8851    }
8852
8853    @Override
8854    public boolean isInLockTaskMode() {
8855        synchronized (this) {
8856            return mStackSupervisor.isInLockTaskMode();
8857        }
8858    }
8859
8860    // =========================================================
8861    // CONTENT PROVIDERS
8862    // =========================================================
8863
8864    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8865        List<ProviderInfo> providers = null;
8866        try {
8867            providers = AppGlobals.getPackageManager().
8868                queryContentProviders(app.processName, app.uid,
8869                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8870        } catch (RemoteException ex) {
8871        }
8872        if (DEBUG_MU)
8873            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8874        int userId = app.userId;
8875        if (providers != null) {
8876            int N = providers.size();
8877            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8878            for (int i=0; i<N; i++) {
8879                ProviderInfo cpi =
8880                    (ProviderInfo)providers.get(i);
8881                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8882                        cpi.name, cpi.flags);
8883                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8884                    // This is a singleton provider, but a user besides the
8885                    // default user is asking to initialize a process it runs
8886                    // in...  well, no, it doesn't actually run in this process,
8887                    // it runs in the process of the default user.  Get rid of it.
8888                    providers.remove(i);
8889                    N--;
8890                    i--;
8891                    continue;
8892                }
8893
8894                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8895                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8896                if (cpr == null) {
8897                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8898                    mProviderMap.putProviderByClass(comp, cpr);
8899                }
8900                if (DEBUG_MU)
8901                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8902                app.pubProviders.put(cpi.name, cpr);
8903                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8904                    // Don't add this if it is a platform component that is marked
8905                    // to run in multiple processes, because this is actually
8906                    // part of the framework so doesn't make sense to track as a
8907                    // separate apk in the process.
8908                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8909                            mProcessStats);
8910                }
8911                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8912            }
8913        }
8914        return providers;
8915    }
8916
8917    /**
8918     * Check if {@link ProcessRecord} has a possible chance at accessing the
8919     * given {@link ProviderInfo}. Final permission checking is always done
8920     * in {@link ContentProvider}.
8921     */
8922    private final String checkContentProviderPermissionLocked(
8923            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8924        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8925        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8926        boolean checkedGrants = false;
8927        if (checkUser) {
8928            // Looking for cross-user grants before enforcing the typical cross-users permissions
8929            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8930            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8931                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8932                    return null;
8933                }
8934                checkedGrants = true;
8935            }
8936            userId = handleIncomingUser(callingPid, callingUid, userId,
8937                    false, ALLOW_NON_FULL,
8938                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8939            if (userId != tmpTargetUserId) {
8940                // When we actually went to determine the final targer user ID, this ended
8941                // up different than our initial check for the authority.  This is because
8942                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8943                // SELF.  So we need to re-check the grants again.
8944                checkedGrants = false;
8945            }
8946        }
8947        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8948                cpi.applicationInfo.uid, cpi.exported)
8949                == PackageManager.PERMISSION_GRANTED) {
8950            return null;
8951        }
8952        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8953                cpi.applicationInfo.uid, cpi.exported)
8954                == PackageManager.PERMISSION_GRANTED) {
8955            return null;
8956        }
8957
8958        PathPermission[] pps = cpi.pathPermissions;
8959        if (pps != null) {
8960            int i = pps.length;
8961            while (i > 0) {
8962                i--;
8963                PathPermission pp = pps[i];
8964                String pprperm = pp.getReadPermission();
8965                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8966                        cpi.applicationInfo.uid, cpi.exported)
8967                        == PackageManager.PERMISSION_GRANTED) {
8968                    return null;
8969                }
8970                String ppwperm = pp.getWritePermission();
8971                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8972                        cpi.applicationInfo.uid, cpi.exported)
8973                        == PackageManager.PERMISSION_GRANTED) {
8974                    return null;
8975                }
8976            }
8977        }
8978        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8979            return null;
8980        }
8981
8982        String msg;
8983        if (!cpi.exported) {
8984            msg = "Permission Denial: opening provider " + cpi.name
8985                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8986                    + ", uid=" + callingUid + ") that is not exported from uid "
8987                    + cpi.applicationInfo.uid;
8988        } else {
8989            msg = "Permission Denial: opening provider " + cpi.name
8990                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8991                    + ", uid=" + callingUid + ") requires "
8992                    + cpi.readPermission + " or " + cpi.writePermission;
8993        }
8994        Slog.w(TAG, msg);
8995        return msg;
8996    }
8997
8998    /**
8999     * Returns if the ContentProvider has granted a uri to callingUid
9000     */
9001    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9002        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9003        if (perms != null) {
9004            for (int i=perms.size()-1; i>=0; i--) {
9005                GrantUri grantUri = perms.keyAt(i);
9006                if (grantUri.sourceUserId == userId || !checkUser) {
9007                    if (matchesProvider(grantUri.uri, cpi)) {
9008                        return true;
9009                    }
9010                }
9011            }
9012        }
9013        return false;
9014    }
9015
9016    /**
9017     * Returns true if the uri authority is one of the authorities specified in the provider.
9018     */
9019    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9020        String uriAuth = uri.getAuthority();
9021        String cpiAuth = cpi.authority;
9022        if (cpiAuth.indexOf(';') == -1) {
9023            return cpiAuth.equals(uriAuth);
9024        }
9025        String[] cpiAuths = cpiAuth.split(";");
9026        int length = cpiAuths.length;
9027        for (int i = 0; i < length; i++) {
9028            if (cpiAuths[i].equals(uriAuth)) return true;
9029        }
9030        return false;
9031    }
9032
9033    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9034            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9035        if (r != null) {
9036            for (int i=0; i<r.conProviders.size(); i++) {
9037                ContentProviderConnection conn = r.conProviders.get(i);
9038                if (conn.provider == cpr) {
9039                    if (DEBUG_PROVIDER) Slog.v(TAG,
9040                            "Adding provider requested by "
9041                            + r.processName + " from process "
9042                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9043                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9044                    if (stable) {
9045                        conn.stableCount++;
9046                        conn.numStableIncs++;
9047                    } else {
9048                        conn.unstableCount++;
9049                        conn.numUnstableIncs++;
9050                    }
9051                    return conn;
9052                }
9053            }
9054            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9055            if (stable) {
9056                conn.stableCount = 1;
9057                conn.numStableIncs = 1;
9058            } else {
9059                conn.unstableCount = 1;
9060                conn.numUnstableIncs = 1;
9061            }
9062            cpr.connections.add(conn);
9063            r.conProviders.add(conn);
9064            return conn;
9065        }
9066        cpr.addExternalProcessHandleLocked(externalProcessToken);
9067        return null;
9068    }
9069
9070    boolean decProviderCountLocked(ContentProviderConnection conn,
9071            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9072        if (conn != null) {
9073            cpr = conn.provider;
9074            if (DEBUG_PROVIDER) Slog.v(TAG,
9075                    "Removing provider requested by "
9076                    + conn.client.processName + " from process "
9077                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9078                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9079            if (stable) {
9080                conn.stableCount--;
9081            } else {
9082                conn.unstableCount--;
9083            }
9084            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9085                cpr.connections.remove(conn);
9086                conn.client.conProviders.remove(conn);
9087                return true;
9088            }
9089            return false;
9090        }
9091        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9092        return false;
9093    }
9094
9095    private void checkTime(long startTime, String where) {
9096        long now = SystemClock.elapsedRealtime();
9097        if ((now-startTime) > 1000) {
9098            // If we are taking more than a second, log about it.
9099            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9100        }
9101    }
9102
9103    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9104            String name, IBinder token, boolean stable, int userId) {
9105        ContentProviderRecord cpr;
9106        ContentProviderConnection conn = null;
9107        ProviderInfo cpi = null;
9108
9109        synchronized(this) {
9110            long startTime = SystemClock.elapsedRealtime();
9111
9112            ProcessRecord r = null;
9113            if (caller != null) {
9114                r = getRecordForAppLocked(caller);
9115                if (r == null) {
9116                    throw new SecurityException(
9117                            "Unable to find app for caller " + caller
9118                          + " (pid=" + Binder.getCallingPid()
9119                          + ") when getting content provider " + name);
9120                }
9121            }
9122
9123            boolean checkCrossUser = true;
9124
9125            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9126
9127            // First check if this content provider has been published...
9128            cpr = mProviderMap.getProviderByName(name, userId);
9129            // If that didn't work, check if it exists for user 0 and then
9130            // verify that it's a singleton provider before using it.
9131            if (cpr == null && userId != UserHandle.USER_OWNER) {
9132                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9133                if (cpr != null) {
9134                    cpi = cpr.info;
9135                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9136                            cpi.name, cpi.flags)
9137                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9138                        userId = UserHandle.USER_OWNER;
9139                        checkCrossUser = false;
9140                    } else {
9141                        cpr = null;
9142                        cpi = null;
9143                    }
9144                }
9145            }
9146
9147            boolean providerRunning = cpr != null;
9148            if (providerRunning) {
9149                cpi = cpr.info;
9150                String msg;
9151                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9152                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9153                        != null) {
9154                    throw new SecurityException(msg);
9155                }
9156                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9157
9158                if (r != null && cpr.canRunHere(r)) {
9159                    // This provider has been published or is in the process
9160                    // of being published...  but it is also allowed to run
9161                    // in the caller's process, so don't make a connection
9162                    // and just let the caller instantiate its own instance.
9163                    ContentProviderHolder holder = cpr.newHolder(null);
9164                    // don't give caller the provider object, it needs
9165                    // to make its own.
9166                    holder.provider = null;
9167                    return holder;
9168                }
9169
9170                final long origId = Binder.clearCallingIdentity();
9171
9172                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9173
9174                // In this case the provider instance already exists, so we can
9175                // return it right away.
9176                conn = incProviderCountLocked(r, cpr, token, stable);
9177                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9178                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9179                        // If this is a perceptible app accessing the provider,
9180                        // make sure to count it as being accessed and thus
9181                        // back up on the LRU list.  This is good because
9182                        // content providers are often expensive to start.
9183                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9184                        updateLruProcessLocked(cpr.proc, false, null);
9185                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9186                    }
9187                }
9188
9189                if (cpr.proc != null) {
9190                    if (false) {
9191                        if (cpr.name.flattenToShortString().equals(
9192                                "com.android.providers.calendar/.CalendarProvider2")) {
9193                            Slog.v(TAG, "****************** KILLING "
9194                                + cpr.name.flattenToShortString());
9195                            Process.killProcess(cpr.proc.pid);
9196                        }
9197                    }
9198                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9199                    boolean success = updateOomAdjLocked(cpr.proc);
9200                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9201                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9202                    // NOTE: there is still a race here where a signal could be
9203                    // pending on the process even though we managed to update its
9204                    // adj level.  Not sure what to do about this, but at least
9205                    // the race is now smaller.
9206                    if (!success) {
9207                        // Uh oh...  it looks like the provider's process
9208                        // has been killed on us.  We need to wait for a new
9209                        // process to be started, and make sure its death
9210                        // doesn't kill our process.
9211                        Slog.i(TAG,
9212                                "Existing provider " + cpr.name.flattenToShortString()
9213                                + " is crashing; detaching " + r);
9214                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9215                        checkTime(startTime, "getContentProviderImpl: before appDied");
9216                        appDiedLocked(cpr.proc);
9217                        checkTime(startTime, "getContentProviderImpl: after appDied");
9218                        if (!lastRef) {
9219                            // This wasn't the last ref our process had on
9220                            // the provider...  we have now been killed, bail.
9221                            return null;
9222                        }
9223                        providerRunning = false;
9224                        conn = null;
9225                    }
9226                }
9227
9228                Binder.restoreCallingIdentity(origId);
9229            }
9230
9231            boolean singleton;
9232            if (!providerRunning) {
9233                try {
9234                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9235                    cpi = AppGlobals.getPackageManager().
9236                        resolveContentProvider(name,
9237                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9238                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9239                } catch (RemoteException ex) {
9240                }
9241                if (cpi == null) {
9242                    return null;
9243                }
9244                // If the provider is a singleton AND
9245                // (it's a call within the same user || the provider is a
9246                // privileged app)
9247                // Then allow connecting to the singleton provider
9248                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9249                        cpi.name, cpi.flags)
9250                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9251                if (singleton) {
9252                    userId = UserHandle.USER_OWNER;
9253                }
9254                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9255                checkTime(startTime, "getContentProviderImpl: got app info for user");
9256
9257                String msg;
9258                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9259                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9260                        != null) {
9261                    throw new SecurityException(msg);
9262                }
9263                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9264
9265                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9266                        && !cpi.processName.equals("system")) {
9267                    // If this content provider does not run in the system
9268                    // process, and the system is not yet ready to run other
9269                    // processes, then fail fast instead of hanging.
9270                    throw new IllegalArgumentException(
9271                            "Attempt to launch content provider before system ready");
9272                }
9273
9274                // Make sure that the user who owns this provider is started.  If not,
9275                // we don't want to allow it to run.
9276                if (mStartedUsers.get(userId) == null) {
9277                    Slog.w(TAG, "Unable to launch app "
9278                            + cpi.applicationInfo.packageName + "/"
9279                            + cpi.applicationInfo.uid + " for provider "
9280                            + name + ": user " + userId + " is stopped");
9281                    return null;
9282                }
9283
9284                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9285                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9286                cpr = mProviderMap.getProviderByClass(comp, userId);
9287                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9288                final boolean firstClass = cpr == null;
9289                if (firstClass) {
9290                    try {
9291                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9292                        ApplicationInfo ai =
9293                            AppGlobals.getPackageManager().
9294                                getApplicationInfo(
9295                                        cpi.applicationInfo.packageName,
9296                                        STOCK_PM_FLAGS, userId);
9297                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9298                        if (ai == null) {
9299                            Slog.w(TAG, "No package info for content provider "
9300                                    + cpi.name);
9301                            return null;
9302                        }
9303                        ai = getAppInfoForUser(ai, userId);
9304                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9305                    } catch (RemoteException ex) {
9306                        // pm is in same process, this will never happen.
9307                    }
9308                }
9309
9310                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9311
9312                if (r != null && cpr.canRunHere(r)) {
9313                    // If this is a multiprocess provider, then just return its
9314                    // info and allow the caller to instantiate it.  Only do
9315                    // this if the provider is the same user as the caller's
9316                    // process, or can run as root (so can be in any process).
9317                    return cpr.newHolder(null);
9318                }
9319
9320                if (DEBUG_PROVIDER) {
9321                    RuntimeException e = new RuntimeException("here");
9322                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9323                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9324                }
9325
9326                // This is single process, and our app is now connecting to it.
9327                // See if we are already in the process of launching this
9328                // provider.
9329                final int N = mLaunchingProviders.size();
9330                int i;
9331                for (i=0; i<N; i++) {
9332                    if (mLaunchingProviders.get(i) == cpr) {
9333                        break;
9334                    }
9335                }
9336
9337                // If the provider is not already being launched, then get it
9338                // started.
9339                if (i >= N) {
9340                    final long origId = Binder.clearCallingIdentity();
9341
9342                    try {
9343                        // Content provider is now in use, its package can't be stopped.
9344                        try {
9345                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9346                            AppGlobals.getPackageManager().setPackageStoppedState(
9347                                    cpr.appInfo.packageName, false, userId);
9348                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9349                        } catch (RemoteException e) {
9350                        } catch (IllegalArgumentException e) {
9351                            Slog.w(TAG, "Failed trying to unstop package "
9352                                    + cpr.appInfo.packageName + ": " + e);
9353                        }
9354
9355                        // Use existing process if already started
9356                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9357                        ProcessRecord proc = getProcessRecordLocked(
9358                                cpi.processName, cpr.appInfo.uid, false);
9359                        if (proc != null && proc.thread != null) {
9360                            if (DEBUG_PROVIDER) {
9361                                Slog.d(TAG, "Installing in existing process " + proc);
9362                            }
9363                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9364                            proc.pubProviders.put(cpi.name, cpr);
9365                            try {
9366                                proc.thread.scheduleInstallProvider(cpi);
9367                            } catch (RemoteException e) {
9368                            }
9369                        } else {
9370                            checkTime(startTime, "getContentProviderImpl: before start process");
9371                            proc = startProcessLocked(cpi.processName,
9372                                    cpr.appInfo, false, 0, "content provider",
9373                                    new ComponentName(cpi.applicationInfo.packageName,
9374                                            cpi.name), false, false, false);
9375                            checkTime(startTime, "getContentProviderImpl: after start process");
9376                            if (proc == null) {
9377                                Slog.w(TAG, "Unable to launch app "
9378                                        + cpi.applicationInfo.packageName + "/"
9379                                        + cpi.applicationInfo.uid + " for provider "
9380                                        + name + ": process is bad");
9381                                return null;
9382                            }
9383                        }
9384                        cpr.launchingApp = proc;
9385                        mLaunchingProviders.add(cpr);
9386                    } finally {
9387                        Binder.restoreCallingIdentity(origId);
9388                    }
9389                }
9390
9391                checkTime(startTime, "getContentProviderImpl: updating data structures");
9392
9393                // Make sure the provider is published (the same provider class
9394                // may be published under multiple names).
9395                if (firstClass) {
9396                    mProviderMap.putProviderByClass(comp, cpr);
9397                }
9398
9399                mProviderMap.putProviderByName(name, cpr);
9400                conn = incProviderCountLocked(r, cpr, token, stable);
9401                if (conn != null) {
9402                    conn.waiting = true;
9403                }
9404            }
9405            checkTime(startTime, "getContentProviderImpl: done!");
9406        }
9407
9408        // Wait for the provider to be published...
9409        synchronized (cpr) {
9410            while (cpr.provider == null) {
9411                if (cpr.launchingApp == null) {
9412                    Slog.w(TAG, "Unable to launch app "
9413                            + cpi.applicationInfo.packageName + "/"
9414                            + cpi.applicationInfo.uid + " for provider "
9415                            + name + ": launching app became null");
9416                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9417                            UserHandle.getUserId(cpi.applicationInfo.uid),
9418                            cpi.applicationInfo.packageName,
9419                            cpi.applicationInfo.uid, name);
9420                    return null;
9421                }
9422                try {
9423                    if (DEBUG_MU) {
9424                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9425                                + cpr.launchingApp);
9426                    }
9427                    if (conn != null) {
9428                        conn.waiting = true;
9429                    }
9430                    cpr.wait();
9431                } catch (InterruptedException ex) {
9432                } finally {
9433                    if (conn != null) {
9434                        conn.waiting = false;
9435                    }
9436                }
9437            }
9438        }
9439        return cpr != null ? cpr.newHolder(conn) : null;
9440    }
9441
9442    @Override
9443    public final ContentProviderHolder getContentProvider(
9444            IApplicationThread caller, String name, int userId, boolean stable) {
9445        enforceNotIsolatedCaller("getContentProvider");
9446        if (caller == null) {
9447            String msg = "null IApplicationThread when getting content provider "
9448                    + name;
9449            Slog.w(TAG, msg);
9450            throw new SecurityException(msg);
9451        }
9452        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9453        // with cross-user grant.
9454        return getContentProviderImpl(caller, name, null, stable, userId);
9455    }
9456
9457    public ContentProviderHolder getContentProviderExternal(
9458            String name, int userId, IBinder token) {
9459        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9460            "Do not have permission in call getContentProviderExternal()");
9461        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9462                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9463        return getContentProviderExternalUnchecked(name, token, userId);
9464    }
9465
9466    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9467            IBinder token, int userId) {
9468        return getContentProviderImpl(null, name, token, true, userId);
9469    }
9470
9471    /**
9472     * Drop a content provider from a ProcessRecord's bookkeeping
9473     */
9474    public void removeContentProvider(IBinder connection, boolean stable) {
9475        enforceNotIsolatedCaller("removeContentProvider");
9476        long ident = Binder.clearCallingIdentity();
9477        try {
9478            synchronized (this) {
9479                ContentProviderConnection conn;
9480                try {
9481                    conn = (ContentProviderConnection)connection;
9482                } catch (ClassCastException e) {
9483                    String msg ="removeContentProvider: " + connection
9484                            + " not a ContentProviderConnection";
9485                    Slog.w(TAG, msg);
9486                    throw new IllegalArgumentException(msg);
9487                }
9488                if (conn == null) {
9489                    throw new NullPointerException("connection is null");
9490                }
9491                if (decProviderCountLocked(conn, null, null, stable)) {
9492                    updateOomAdjLocked();
9493                }
9494            }
9495        } finally {
9496            Binder.restoreCallingIdentity(ident);
9497        }
9498    }
9499
9500    public void removeContentProviderExternal(String name, IBinder token) {
9501        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9502            "Do not have permission in call removeContentProviderExternal()");
9503        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9504    }
9505
9506    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9507        synchronized (this) {
9508            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9509            if(cpr == null) {
9510                //remove from mProvidersByClass
9511                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9512                return;
9513            }
9514
9515            //update content provider record entry info
9516            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9517            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9518            if (localCpr.hasExternalProcessHandles()) {
9519                if (localCpr.removeExternalProcessHandleLocked(token)) {
9520                    updateOomAdjLocked();
9521                } else {
9522                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9523                            + " with no external reference for token: "
9524                            + token + ".");
9525                }
9526            } else {
9527                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9528                        + " with no external references.");
9529            }
9530        }
9531    }
9532
9533    public final void publishContentProviders(IApplicationThread caller,
9534            List<ContentProviderHolder> providers) {
9535        if (providers == null) {
9536            return;
9537        }
9538
9539        enforceNotIsolatedCaller("publishContentProviders");
9540        synchronized (this) {
9541            final ProcessRecord r = getRecordForAppLocked(caller);
9542            if (DEBUG_MU)
9543                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9544            if (r == null) {
9545                throw new SecurityException(
9546                        "Unable to find app for caller " + caller
9547                      + " (pid=" + Binder.getCallingPid()
9548                      + ") when publishing content providers");
9549            }
9550
9551            final long origId = Binder.clearCallingIdentity();
9552
9553            final int N = providers.size();
9554            for (int i=0; i<N; i++) {
9555                ContentProviderHolder src = providers.get(i);
9556                if (src == null || src.info == null || src.provider == null) {
9557                    continue;
9558                }
9559                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9560                if (DEBUG_MU)
9561                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9562                if (dst != null) {
9563                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9564                    mProviderMap.putProviderByClass(comp, dst);
9565                    String names[] = dst.info.authority.split(";");
9566                    for (int j = 0; j < names.length; j++) {
9567                        mProviderMap.putProviderByName(names[j], dst);
9568                    }
9569
9570                    int NL = mLaunchingProviders.size();
9571                    int j;
9572                    for (j=0; j<NL; j++) {
9573                        if (mLaunchingProviders.get(j) == dst) {
9574                            mLaunchingProviders.remove(j);
9575                            j--;
9576                            NL--;
9577                        }
9578                    }
9579                    synchronized (dst) {
9580                        dst.provider = src.provider;
9581                        dst.proc = r;
9582                        dst.notifyAll();
9583                    }
9584                    updateOomAdjLocked(r);
9585                }
9586            }
9587
9588            Binder.restoreCallingIdentity(origId);
9589        }
9590    }
9591
9592    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9593        ContentProviderConnection conn;
9594        try {
9595            conn = (ContentProviderConnection)connection;
9596        } catch (ClassCastException e) {
9597            String msg ="refContentProvider: " + connection
9598                    + " not a ContentProviderConnection";
9599            Slog.w(TAG, msg);
9600            throw new IllegalArgumentException(msg);
9601        }
9602        if (conn == null) {
9603            throw new NullPointerException("connection is null");
9604        }
9605
9606        synchronized (this) {
9607            if (stable > 0) {
9608                conn.numStableIncs += stable;
9609            }
9610            stable = conn.stableCount + stable;
9611            if (stable < 0) {
9612                throw new IllegalStateException("stableCount < 0: " + stable);
9613            }
9614
9615            if (unstable > 0) {
9616                conn.numUnstableIncs += unstable;
9617            }
9618            unstable = conn.unstableCount + unstable;
9619            if (unstable < 0) {
9620                throw new IllegalStateException("unstableCount < 0: " + unstable);
9621            }
9622
9623            if ((stable+unstable) <= 0) {
9624                throw new IllegalStateException("ref counts can't go to zero here: stable="
9625                        + stable + " unstable=" + unstable);
9626            }
9627            conn.stableCount = stable;
9628            conn.unstableCount = unstable;
9629            return !conn.dead;
9630        }
9631    }
9632
9633    public void unstableProviderDied(IBinder connection) {
9634        ContentProviderConnection conn;
9635        try {
9636            conn = (ContentProviderConnection)connection;
9637        } catch (ClassCastException e) {
9638            String msg ="refContentProvider: " + connection
9639                    + " not a ContentProviderConnection";
9640            Slog.w(TAG, msg);
9641            throw new IllegalArgumentException(msg);
9642        }
9643        if (conn == null) {
9644            throw new NullPointerException("connection is null");
9645        }
9646
9647        // Safely retrieve the content provider associated with the connection.
9648        IContentProvider provider;
9649        synchronized (this) {
9650            provider = conn.provider.provider;
9651        }
9652
9653        if (provider == null) {
9654            // Um, yeah, we're way ahead of you.
9655            return;
9656        }
9657
9658        // Make sure the caller is being honest with us.
9659        if (provider.asBinder().pingBinder()) {
9660            // Er, no, still looks good to us.
9661            synchronized (this) {
9662                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9663                        + " says " + conn + " died, but we don't agree");
9664                return;
9665            }
9666        }
9667
9668        // Well look at that!  It's dead!
9669        synchronized (this) {
9670            if (conn.provider.provider != provider) {
9671                // But something changed...  good enough.
9672                return;
9673            }
9674
9675            ProcessRecord proc = conn.provider.proc;
9676            if (proc == null || proc.thread == null) {
9677                // Seems like the process is already cleaned up.
9678                return;
9679            }
9680
9681            // As far as we're concerned, this is just like receiving a
9682            // death notification...  just a bit prematurely.
9683            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9684                    + ") early provider death");
9685            final long ident = Binder.clearCallingIdentity();
9686            try {
9687                appDiedLocked(proc);
9688            } finally {
9689                Binder.restoreCallingIdentity(ident);
9690            }
9691        }
9692    }
9693
9694    @Override
9695    public void appNotRespondingViaProvider(IBinder connection) {
9696        enforceCallingPermission(
9697                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9698
9699        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9700        if (conn == null) {
9701            Slog.w(TAG, "ContentProviderConnection is null");
9702            return;
9703        }
9704
9705        final ProcessRecord host = conn.provider.proc;
9706        if (host == null) {
9707            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9708            return;
9709        }
9710
9711        final long token = Binder.clearCallingIdentity();
9712        try {
9713            appNotResponding(host, null, null, false, "ContentProvider not responding");
9714        } finally {
9715            Binder.restoreCallingIdentity(token);
9716        }
9717    }
9718
9719    public final void installSystemProviders() {
9720        List<ProviderInfo> providers;
9721        synchronized (this) {
9722            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9723            providers = generateApplicationProvidersLocked(app);
9724            if (providers != null) {
9725                for (int i=providers.size()-1; i>=0; i--) {
9726                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9727                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9728                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9729                                + ": not system .apk");
9730                        providers.remove(i);
9731                    }
9732                }
9733            }
9734        }
9735        if (providers != null) {
9736            mSystemThread.installSystemProviders(providers);
9737        }
9738
9739        mCoreSettingsObserver = new CoreSettingsObserver(this);
9740
9741        //mUsageStatsService.monitorPackages();
9742    }
9743
9744    /**
9745     * Allows apps to retrieve the MIME type of a URI.
9746     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9747     * users, then it does not need permission to access the ContentProvider.
9748     * Either, it needs cross-user uri grants.
9749     *
9750     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9751     *
9752     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9753     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9754     */
9755    public String getProviderMimeType(Uri uri, int userId) {
9756        enforceNotIsolatedCaller("getProviderMimeType");
9757        final String name = uri.getAuthority();
9758        int callingUid = Binder.getCallingUid();
9759        int callingPid = Binder.getCallingPid();
9760        long ident = 0;
9761        boolean clearedIdentity = false;
9762        userId = unsafeConvertIncomingUser(userId);
9763        if (canClearIdentity(callingPid, callingUid, userId)) {
9764            clearedIdentity = true;
9765            ident = Binder.clearCallingIdentity();
9766        }
9767        ContentProviderHolder holder = null;
9768        try {
9769            holder = getContentProviderExternalUnchecked(name, null, userId);
9770            if (holder != null) {
9771                return holder.provider.getType(uri);
9772            }
9773        } catch (RemoteException e) {
9774            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9775            return null;
9776        } finally {
9777            // We need to clear the identity to call removeContentProviderExternalUnchecked
9778            if (!clearedIdentity) {
9779                ident = Binder.clearCallingIdentity();
9780            }
9781            try {
9782                if (holder != null) {
9783                    removeContentProviderExternalUnchecked(name, null, userId);
9784                }
9785            } finally {
9786                Binder.restoreCallingIdentity(ident);
9787            }
9788        }
9789
9790        return null;
9791    }
9792
9793    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9794        if (UserHandle.getUserId(callingUid) == userId) {
9795            return true;
9796        }
9797        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9798                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9799                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9800                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9801                return true;
9802        }
9803        return false;
9804    }
9805
9806    // =========================================================
9807    // GLOBAL MANAGEMENT
9808    // =========================================================
9809
9810    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9811            boolean isolated, int isolatedUid) {
9812        String proc = customProcess != null ? customProcess : info.processName;
9813        BatteryStatsImpl.Uid.Proc ps = null;
9814        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9815        int uid = info.uid;
9816        if (isolated) {
9817            if (isolatedUid == 0) {
9818                int userId = UserHandle.getUserId(uid);
9819                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9820                while (true) {
9821                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9822                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9823                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9824                    }
9825                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9826                    mNextIsolatedProcessUid++;
9827                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9828                        // No process for this uid, use it.
9829                        break;
9830                    }
9831                    stepsLeft--;
9832                    if (stepsLeft <= 0) {
9833                        return null;
9834                    }
9835                }
9836            } else {
9837                // Special case for startIsolatedProcess (internal only), where
9838                // the uid of the isolated process is specified by the caller.
9839                uid = isolatedUid;
9840            }
9841        }
9842        return new ProcessRecord(stats, info, proc, uid);
9843    }
9844
9845    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9846            String abiOverride) {
9847        ProcessRecord app;
9848        if (!isolated) {
9849            app = getProcessRecordLocked(info.processName, info.uid, true);
9850        } else {
9851            app = null;
9852        }
9853
9854        if (app == null) {
9855            app = newProcessRecordLocked(info, null, isolated, 0);
9856            mProcessNames.put(info.processName, app.uid, app);
9857            if (isolated) {
9858                mIsolatedProcesses.put(app.uid, app);
9859            }
9860            updateLruProcessLocked(app, false, null);
9861            updateOomAdjLocked();
9862        }
9863
9864        // This package really, really can not be stopped.
9865        try {
9866            AppGlobals.getPackageManager().setPackageStoppedState(
9867                    info.packageName, false, UserHandle.getUserId(app.uid));
9868        } catch (RemoteException e) {
9869        } catch (IllegalArgumentException e) {
9870            Slog.w(TAG, "Failed trying to unstop package "
9871                    + info.packageName + ": " + e);
9872        }
9873
9874        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9875                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9876            app.persistent = true;
9877            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9878        }
9879        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9880            mPersistentStartingProcesses.add(app);
9881            startProcessLocked(app, "added application", app.processName, abiOverride,
9882                    null /* entryPoint */, null /* entryPointArgs */);
9883        }
9884
9885        return app;
9886    }
9887
9888    public void unhandledBack() {
9889        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9890                "unhandledBack()");
9891
9892        synchronized(this) {
9893            final long origId = Binder.clearCallingIdentity();
9894            try {
9895                getFocusedStack().unhandledBackLocked();
9896            } finally {
9897                Binder.restoreCallingIdentity(origId);
9898            }
9899        }
9900    }
9901
9902    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9903        enforceNotIsolatedCaller("openContentUri");
9904        final int userId = UserHandle.getCallingUserId();
9905        String name = uri.getAuthority();
9906        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9907        ParcelFileDescriptor pfd = null;
9908        if (cph != null) {
9909            // We record the binder invoker's uid in thread-local storage before
9910            // going to the content provider to open the file.  Later, in the code
9911            // that handles all permissions checks, we look for this uid and use
9912            // that rather than the Activity Manager's own uid.  The effect is that
9913            // we do the check against the caller's permissions even though it looks
9914            // to the content provider like the Activity Manager itself is making
9915            // the request.
9916            sCallerIdentity.set(new Identity(
9917                    Binder.getCallingPid(), Binder.getCallingUid()));
9918            try {
9919                pfd = cph.provider.openFile(null, uri, "r", null);
9920            } catch (FileNotFoundException e) {
9921                // do nothing; pfd will be returned null
9922            } finally {
9923                // Ensure that whatever happens, we clean up the identity state
9924                sCallerIdentity.remove();
9925            }
9926
9927            // We've got the fd now, so we're done with the provider.
9928            removeContentProviderExternalUnchecked(name, null, userId);
9929        } else {
9930            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9931        }
9932        return pfd;
9933    }
9934
9935    // Actually is sleeping or shutting down or whatever else in the future
9936    // is an inactive state.
9937    public boolean isSleepingOrShuttingDown() {
9938        return mSleeping || mShuttingDown;
9939    }
9940
9941    public boolean isSleeping() {
9942        return mSleeping;
9943    }
9944
9945    void goingToSleep() {
9946        synchronized(this) {
9947            mWentToSleep = true;
9948            updateEventDispatchingLocked();
9949            goToSleepIfNeededLocked();
9950        }
9951    }
9952
9953    void finishRunningVoiceLocked() {
9954        if (mRunningVoice) {
9955            mRunningVoice = false;
9956            goToSleepIfNeededLocked();
9957        }
9958    }
9959
9960    void goToSleepIfNeededLocked() {
9961        if (mWentToSleep && !mRunningVoice) {
9962            if (!mSleeping) {
9963                mSleeping = true;
9964                mStackSupervisor.goingToSleepLocked();
9965
9966                // Initialize the wake times of all processes.
9967                checkExcessivePowerUsageLocked(false);
9968                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9969                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9970                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9971            }
9972        }
9973    }
9974
9975    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9976        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9977            // Never persist the home stack.
9978            return;
9979        }
9980        mTaskPersister.wakeup(task, flush);
9981    }
9982
9983    @Override
9984    public boolean shutdown(int timeout) {
9985        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9986                != PackageManager.PERMISSION_GRANTED) {
9987            throw new SecurityException("Requires permission "
9988                    + android.Manifest.permission.SHUTDOWN);
9989        }
9990
9991        boolean timedout = false;
9992
9993        synchronized(this) {
9994            mShuttingDown = true;
9995            updateEventDispatchingLocked();
9996            timedout = mStackSupervisor.shutdownLocked(timeout);
9997        }
9998
9999        mAppOpsService.shutdown();
10000        if (mUsageStatsService != null) {
10001            mUsageStatsService.prepareShutdown();
10002        }
10003        mBatteryStatsService.shutdown();
10004        synchronized (this) {
10005            mProcessStats.shutdownLocked();
10006        }
10007        notifyTaskPersisterLocked(null, true);
10008
10009        return timedout;
10010    }
10011
10012    public final void activitySlept(IBinder token) {
10013        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10014
10015        final long origId = Binder.clearCallingIdentity();
10016
10017        synchronized (this) {
10018            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10019            if (r != null) {
10020                mStackSupervisor.activitySleptLocked(r);
10021            }
10022        }
10023
10024        Binder.restoreCallingIdentity(origId);
10025    }
10026
10027    void logLockScreen(String msg) {
10028        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10029                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10030                mWentToSleep + " mSleeping=" + mSleeping);
10031    }
10032
10033    private void comeOutOfSleepIfNeededLocked() {
10034        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10035            if (mSleeping) {
10036                mSleeping = false;
10037                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10038            }
10039        }
10040    }
10041
10042    void wakingUp() {
10043        synchronized(this) {
10044            mWentToSleep = false;
10045            updateEventDispatchingLocked();
10046            comeOutOfSleepIfNeededLocked();
10047        }
10048    }
10049
10050    void startRunningVoiceLocked() {
10051        if (!mRunningVoice) {
10052            mRunningVoice = true;
10053            comeOutOfSleepIfNeededLocked();
10054        }
10055    }
10056
10057    private void updateEventDispatchingLocked() {
10058        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10059    }
10060
10061    public void setLockScreenShown(boolean shown) {
10062        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10063                != PackageManager.PERMISSION_GRANTED) {
10064            throw new SecurityException("Requires permission "
10065                    + android.Manifest.permission.DEVICE_POWER);
10066        }
10067
10068        synchronized(this) {
10069            long ident = Binder.clearCallingIdentity();
10070            try {
10071                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10072                mLockScreenShown = shown;
10073                comeOutOfSleepIfNeededLocked();
10074            } finally {
10075                Binder.restoreCallingIdentity(ident);
10076            }
10077        }
10078    }
10079
10080    @Override
10081    public void stopAppSwitches() {
10082        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10083                != PackageManager.PERMISSION_GRANTED) {
10084            throw new SecurityException("Requires permission "
10085                    + android.Manifest.permission.STOP_APP_SWITCHES);
10086        }
10087
10088        synchronized(this) {
10089            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10090                    + APP_SWITCH_DELAY_TIME;
10091            mDidAppSwitch = false;
10092            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10093            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10094            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10095        }
10096    }
10097
10098    public void resumeAppSwitches() {
10099        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10100                != PackageManager.PERMISSION_GRANTED) {
10101            throw new SecurityException("Requires permission "
10102                    + android.Manifest.permission.STOP_APP_SWITCHES);
10103        }
10104
10105        synchronized(this) {
10106            // Note that we don't execute any pending app switches... we will
10107            // let those wait until either the timeout, or the next start
10108            // activity request.
10109            mAppSwitchesAllowedTime = 0;
10110        }
10111    }
10112
10113    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10114            String name) {
10115        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10116            return true;
10117        }
10118
10119        final int perm = checkComponentPermission(
10120                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10121                callingUid, -1, true);
10122        if (perm == PackageManager.PERMISSION_GRANTED) {
10123            return true;
10124        }
10125
10126        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10127        return false;
10128    }
10129
10130    public void setDebugApp(String packageName, boolean waitForDebugger,
10131            boolean persistent) {
10132        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10133                "setDebugApp()");
10134
10135        long ident = Binder.clearCallingIdentity();
10136        try {
10137            // Note that this is not really thread safe if there are multiple
10138            // callers into it at the same time, but that's not a situation we
10139            // care about.
10140            if (persistent) {
10141                final ContentResolver resolver = mContext.getContentResolver();
10142                Settings.Global.putString(
10143                    resolver, Settings.Global.DEBUG_APP,
10144                    packageName);
10145                Settings.Global.putInt(
10146                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10147                    waitForDebugger ? 1 : 0);
10148            }
10149
10150            synchronized (this) {
10151                if (!persistent) {
10152                    mOrigDebugApp = mDebugApp;
10153                    mOrigWaitForDebugger = mWaitForDebugger;
10154                }
10155                mDebugApp = packageName;
10156                mWaitForDebugger = waitForDebugger;
10157                mDebugTransient = !persistent;
10158                if (packageName != null) {
10159                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10160                            false, UserHandle.USER_ALL, "set debug app");
10161                }
10162            }
10163        } finally {
10164            Binder.restoreCallingIdentity(ident);
10165        }
10166    }
10167
10168    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10169        synchronized (this) {
10170            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10171            if (!isDebuggable) {
10172                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10173                    throw new SecurityException("Process not debuggable: " + app.packageName);
10174                }
10175            }
10176
10177            mOpenGlTraceApp = processName;
10178        }
10179    }
10180
10181    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10182        synchronized (this) {
10183            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10184            if (!isDebuggable) {
10185                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10186                    throw new SecurityException("Process not debuggable: " + app.packageName);
10187                }
10188            }
10189            mProfileApp = processName;
10190            mProfileFile = profilerInfo.profileFile;
10191            if (mProfileFd != null) {
10192                try {
10193                    mProfileFd.close();
10194                } catch (IOException e) {
10195                }
10196                mProfileFd = null;
10197            }
10198            mProfileFd = profilerInfo.profileFd;
10199            mSamplingInterval = profilerInfo.samplingInterval;
10200            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10201            mProfileType = 0;
10202        }
10203    }
10204
10205    @Override
10206    public void setAlwaysFinish(boolean enabled) {
10207        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10208                "setAlwaysFinish()");
10209
10210        Settings.Global.putInt(
10211                mContext.getContentResolver(),
10212                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10213
10214        synchronized (this) {
10215            mAlwaysFinishActivities = enabled;
10216        }
10217    }
10218
10219    @Override
10220    public void setActivityController(IActivityController controller) {
10221        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10222                "setActivityController()");
10223        synchronized (this) {
10224            mController = controller;
10225            Watchdog.getInstance().setActivityController(controller);
10226        }
10227    }
10228
10229    @Override
10230    public void setUserIsMonkey(boolean userIsMonkey) {
10231        synchronized (this) {
10232            synchronized (mPidsSelfLocked) {
10233                final int callingPid = Binder.getCallingPid();
10234                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10235                if (precessRecord == null) {
10236                    throw new SecurityException("Unknown process: " + callingPid);
10237                }
10238                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10239                    throw new SecurityException("Only an instrumentation process "
10240                            + "with a UiAutomation can call setUserIsMonkey");
10241                }
10242            }
10243            mUserIsMonkey = userIsMonkey;
10244        }
10245    }
10246
10247    @Override
10248    public boolean isUserAMonkey() {
10249        synchronized (this) {
10250            // If there is a controller also implies the user is a monkey.
10251            return (mUserIsMonkey || mController != null);
10252        }
10253    }
10254
10255    public void requestBugReport() {
10256        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10257        SystemProperties.set("ctl.start", "bugreport");
10258    }
10259
10260    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10261        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10262    }
10263
10264    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10265        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10266            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10267        }
10268        return KEY_DISPATCHING_TIMEOUT;
10269    }
10270
10271    @Override
10272    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10273        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10274                != PackageManager.PERMISSION_GRANTED) {
10275            throw new SecurityException("Requires permission "
10276                    + android.Manifest.permission.FILTER_EVENTS);
10277        }
10278        ProcessRecord proc;
10279        long timeout;
10280        synchronized (this) {
10281            synchronized (mPidsSelfLocked) {
10282                proc = mPidsSelfLocked.get(pid);
10283            }
10284            timeout = getInputDispatchingTimeoutLocked(proc);
10285        }
10286
10287        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10288            return -1;
10289        }
10290
10291        return timeout;
10292    }
10293
10294    /**
10295     * Handle input dispatching timeouts.
10296     * Returns whether input dispatching should be aborted or not.
10297     */
10298    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10299            final ActivityRecord activity, final ActivityRecord parent,
10300            final boolean aboveSystem, String reason) {
10301        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10302                != PackageManager.PERMISSION_GRANTED) {
10303            throw new SecurityException("Requires permission "
10304                    + android.Manifest.permission.FILTER_EVENTS);
10305        }
10306
10307        final String annotation;
10308        if (reason == null) {
10309            annotation = "Input dispatching timed out";
10310        } else {
10311            annotation = "Input dispatching timed out (" + reason + ")";
10312        }
10313
10314        if (proc != null) {
10315            synchronized (this) {
10316                if (proc.debugging) {
10317                    return false;
10318                }
10319
10320                if (mDidDexOpt) {
10321                    // Give more time since we were dexopting.
10322                    mDidDexOpt = false;
10323                    return false;
10324                }
10325
10326                if (proc.instrumentationClass != null) {
10327                    Bundle info = new Bundle();
10328                    info.putString("shortMsg", "keyDispatchingTimedOut");
10329                    info.putString("longMsg", annotation);
10330                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10331                    return true;
10332                }
10333            }
10334            mHandler.post(new Runnable() {
10335                @Override
10336                public void run() {
10337                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10338                }
10339            });
10340        }
10341
10342        return true;
10343    }
10344
10345    public Bundle getAssistContextExtras(int requestType) {
10346        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10347                "getAssistContextExtras()");
10348        PendingAssistExtras pae;
10349        Bundle extras = new Bundle();
10350        synchronized (this) {
10351            ActivityRecord activity = getFocusedStack().mResumedActivity;
10352            if (activity == null) {
10353                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10354                return null;
10355            }
10356            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10357            if (activity.app == null || activity.app.thread == null) {
10358                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10359                return extras;
10360            }
10361            if (activity.app.pid == Binder.getCallingPid()) {
10362                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10363                return extras;
10364            }
10365            pae = new PendingAssistExtras(activity);
10366            try {
10367                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10368                        requestType);
10369                mPendingAssistExtras.add(pae);
10370                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10371            } catch (RemoteException e) {
10372                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10373                return extras;
10374            }
10375        }
10376        synchronized (pae) {
10377            while (!pae.haveResult) {
10378                try {
10379                    pae.wait();
10380                } catch (InterruptedException e) {
10381                }
10382            }
10383            if (pae.result != null) {
10384                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10385            }
10386        }
10387        synchronized (this) {
10388            mPendingAssistExtras.remove(pae);
10389            mHandler.removeCallbacks(pae);
10390        }
10391        return extras;
10392    }
10393
10394    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10395        PendingAssistExtras pae = (PendingAssistExtras)token;
10396        synchronized (pae) {
10397            pae.result = extras;
10398            pae.haveResult = true;
10399            pae.notifyAll();
10400        }
10401    }
10402
10403    public void registerProcessObserver(IProcessObserver observer) {
10404        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10405                "registerProcessObserver()");
10406        synchronized (this) {
10407            mProcessObservers.register(observer);
10408        }
10409    }
10410
10411    @Override
10412    public void unregisterProcessObserver(IProcessObserver observer) {
10413        synchronized (this) {
10414            mProcessObservers.unregister(observer);
10415        }
10416    }
10417
10418    @Override
10419    public boolean convertFromTranslucent(IBinder token) {
10420        final long origId = Binder.clearCallingIdentity();
10421        try {
10422            synchronized (this) {
10423                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10424                if (r == null) {
10425                    return false;
10426                }
10427                final boolean translucentChanged = r.changeWindowTranslucency(true);
10428                if (translucentChanged) {
10429                    r.task.stack.releaseBackgroundResources();
10430                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10431                }
10432                mWindowManager.setAppFullscreen(token, true);
10433                return translucentChanged;
10434            }
10435        } finally {
10436            Binder.restoreCallingIdentity(origId);
10437        }
10438    }
10439
10440    @Override
10441    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10442        final long origId = Binder.clearCallingIdentity();
10443        try {
10444            synchronized (this) {
10445                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10446                if (r == null) {
10447                    return false;
10448                }
10449                int index = r.task.mActivities.lastIndexOf(r);
10450                if (index > 0) {
10451                    ActivityRecord under = r.task.mActivities.get(index - 1);
10452                    under.returningOptions = options;
10453                }
10454                final boolean translucentChanged = r.changeWindowTranslucency(false);
10455                if (translucentChanged) {
10456                    r.task.stack.convertToTranslucent(r);
10457                }
10458                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10459                mWindowManager.setAppFullscreen(token, false);
10460                return translucentChanged;
10461            }
10462        } finally {
10463            Binder.restoreCallingIdentity(origId);
10464        }
10465    }
10466
10467    @Override
10468    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10469        final long origId = Binder.clearCallingIdentity();
10470        try {
10471            synchronized (this) {
10472                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10473                if (r != null) {
10474                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10475                }
10476            }
10477            return false;
10478        } finally {
10479            Binder.restoreCallingIdentity(origId);
10480        }
10481    }
10482
10483    @Override
10484    public boolean isBackgroundVisibleBehind(IBinder token) {
10485        final long origId = Binder.clearCallingIdentity();
10486        try {
10487            synchronized (this) {
10488                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10489                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10490                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10491                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10492                return visible;
10493            }
10494        } finally {
10495            Binder.restoreCallingIdentity(origId);
10496        }
10497    }
10498
10499    @Override
10500    public ActivityOptions getActivityOptions(IBinder token) {
10501        final long origId = Binder.clearCallingIdentity();
10502        try {
10503            synchronized (this) {
10504                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10505                if (r != null) {
10506                    final ActivityOptions activityOptions = r.pendingOptions;
10507                    r.pendingOptions = null;
10508                    return activityOptions;
10509                }
10510                return null;
10511            }
10512        } finally {
10513            Binder.restoreCallingIdentity(origId);
10514        }
10515    }
10516
10517    @Override
10518    public void setImmersive(IBinder token, boolean immersive) {
10519        synchronized(this) {
10520            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10521            if (r == null) {
10522                throw new IllegalArgumentException();
10523            }
10524            r.immersive = immersive;
10525
10526            // update associated state if we're frontmost
10527            if (r == mFocusedActivity) {
10528                if (DEBUG_IMMERSIVE) {
10529                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10530                }
10531                applyUpdateLockStateLocked(r);
10532            }
10533        }
10534    }
10535
10536    @Override
10537    public boolean isImmersive(IBinder token) {
10538        synchronized (this) {
10539            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10540            if (r == null) {
10541                throw new IllegalArgumentException();
10542            }
10543            return r.immersive;
10544        }
10545    }
10546
10547    public boolean isTopActivityImmersive() {
10548        enforceNotIsolatedCaller("startActivity");
10549        synchronized (this) {
10550            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10551            return (r != null) ? r.immersive : false;
10552        }
10553    }
10554
10555    @Override
10556    public boolean isTopOfTask(IBinder token) {
10557        synchronized (this) {
10558            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10559            if (r == null) {
10560                throw new IllegalArgumentException();
10561            }
10562            return r.task.getTopActivity() == r;
10563        }
10564    }
10565
10566    public final void enterSafeMode() {
10567        synchronized(this) {
10568            // It only makes sense to do this before the system is ready
10569            // and started launching other packages.
10570            if (!mSystemReady) {
10571                try {
10572                    AppGlobals.getPackageManager().enterSafeMode();
10573                } catch (RemoteException e) {
10574                }
10575            }
10576
10577            mSafeMode = true;
10578        }
10579    }
10580
10581    public final void showSafeModeOverlay() {
10582        View v = LayoutInflater.from(mContext).inflate(
10583                com.android.internal.R.layout.safe_mode, null);
10584        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10585        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10586        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10587        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10588        lp.gravity = Gravity.BOTTOM | Gravity.START;
10589        lp.format = v.getBackground().getOpacity();
10590        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10591                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10592        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10593        ((WindowManager)mContext.getSystemService(
10594                Context.WINDOW_SERVICE)).addView(v, lp);
10595    }
10596
10597    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10598        if (!(sender instanceof PendingIntentRecord)) {
10599            return;
10600        }
10601        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10602        synchronized (stats) {
10603            if (mBatteryStatsService.isOnBattery()) {
10604                mBatteryStatsService.enforceCallingPermission();
10605                PendingIntentRecord rec = (PendingIntentRecord)sender;
10606                int MY_UID = Binder.getCallingUid();
10607                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10608                BatteryStatsImpl.Uid.Pkg pkg =
10609                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10610                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10611                pkg.incWakeupsLocked();
10612            }
10613        }
10614    }
10615
10616    public boolean killPids(int[] pids, String pReason, boolean secure) {
10617        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10618            throw new SecurityException("killPids only available to the system");
10619        }
10620        String reason = (pReason == null) ? "Unknown" : pReason;
10621        // XXX Note: don't acquire main activity lock here, because the window
10622        // manager calls in with its locks held.
10623
10624        boolean killed = false;
10625        synchronized (mPidsSelfLocked) {
10626            int[] types = new int[pids.length];
10627            int worstType = 0;
10628            for (int i=0; i<pids.length; i++) {
10629                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10630                if (proc != null) {
10631                    int type = proc.setAdj;
10632                    types[i] = type;
10633                    if (type > worstType) {
10634                        worstType = type;
10635                    }
10636                }
10637            }
10638
10639            // If the worst oom_adj is somewhere in the cached proc LRU range,
10640            // then constrain it so we will kill all cached procs.
10641            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10642                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10643                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10644            }
10645
10646            // If this is not a secure call, don't let it kill processes that
10647            // are important.
10648            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10649                worstType = ProcessList.SERVICE_ADJ;
10650            }
10651
10652            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10653            for (int i=0; i<pids.length; i++) {
10654                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10655                if (proc == null) {
10656                    continue;
10657                }
10658                int adj = proc.setAdj;
10659                if (adj >= worstType && !proc.killedByAm) {
10660                    proc.kill(reason, true);
10661                    killed = true;
10662                }
10663            }
10664        }
10665        return killed;
10666    }
10667
10668    @Override
10669    public void killUid(int uid, String reason) {
10670        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10671            throw new SecurityException("killUid only available to the system");
10672        }
10673        synchronized (this) {
10674            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10675                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10676                    reason != null ? reason : "kill uid");
10677        }
10678    }
10679
10680    @Override
10681    public boolean killProcessesBelowForeground(String reason) {
10682        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10683            throw new SecurityException("killProcessesBelowForeground() only available to system");
10684        }
10685
10686        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10687    }
10688
10689    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10690        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10691            throw new SecurityException("killProcessesBelowAdj() only available to system");
10692        }
10693
10694        boolean killed = false;
10695        synchronized (mPidsSelfLocked) {
10696            final int size = mPidsSelfLocked.size();
10697            for (int i = 0; i < size; i++) {
10698                final int pid = mPidsSelfLocked.keyAt(i);
10699                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10700                if (proc == null) continue;
10701
10702                final int adj = proc.setAdj;
10703                if (adj > belowAdj && !proc.killedByAm) {
10704                    proc.kill(reason, true);
10705                    killed = true;
10706                }
10707            }
10708        }
10709        return killed;
10710    }
10711
10712    @Override
10713    public void hang(final IBinder who, boolean allowRestart) {
10714        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10715                != PackageManager.PERMISSION_GRANTED) {
10716            throw new SecurityException("Requires permission "
10717                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10718        }
10719
10720        final IBinder.DeathRecipient death = new DeathRecipient() {
10721            @Override
10722            public void binderDied() {
10723                synchronized (this) {
10724                    notifyAll();
10725                }
10726            }
10727        };
10728
10729        try {
10730            who.linkToDeath(death, 0);
10731        } catch (RemoteException e) {
10732            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10733            return;
10734        }
10735
10736        synchronized (this) {
10737            Watchdog.getInstance().setAllowRestart(allowRestart);
10738            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10739            synchronized (death) {
10740                while (who.isBinderAlive()) {
10741                    try {
10742                        death.wait();
10743                    } catch (InterruptedException e) {
10744                    }
10745                }
10746            }
10747            Watchdog.getInstance().setAllowRestart(true);
10748        }
10749    }
10750
10751    @Override
10752    public void restart() {
10753        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10754                != PackageManager.PERMISSION_GRANTED) {
10755            throw new SecurityException("Requires permission "
10756                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10757        }
10758
10759        Log.i(TAG, "Sending shutdown broadcast...");
10760
10761        BroadcastReceiver br = new BroadcastReceiver() {
10762            @Override public void onReceive(Context context, Intent intent) {
10763                // Now the broadcast is done, finish up the low-level shutdown.
10764                Log.i(TAG, "Shutting down activity manager...");
10765                shutdown(10000);
10766                Log.i(TAG, "Shutdown complete, restarting!");
10767                Process.killProcess(Process.myPid());
10768                System.exit(10);
10769            }
10770        };
10771
10772        // First send the high-level shut down broadcast.
10773        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10774        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10775        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10776        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10777        mContext.sendOrderedBroadcastAsUser(intent,
10778                UserHandle.ALL, null, br, mHandler, 0, null, null);
10779        */
10780        br.onReceive(mContext, intent);
10781    }
10782
10783    private long getLowRamTimeSinceIdle(long now) {
10784        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10785    }
10786
10787    @Override
10788    public void performIdleMaintenance() {
10789        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10790                != PackageManager.PERMISSION_GRANTED) {
10791            throw new SecurityException("Requires permission "
10792                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10793        }
10794
10795        synchronized (this) {
10796            final long now = SystemClock.uptimeMillis();
10797            final long timeSinceLastIdle = now - mLastIdleTime;
10798            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10799            mLastIdleTime = now;
10800            mLowRamTimeSinceLastIdle = 0;
10801            if (mLowRamStartTime != 0) {
10802                mLowRamStartTime = now;
10803            }
10804
10805            StringBuilder sb = new StringBuilder(128);
10806            sb.append("Idle maintenance over ");
10807            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10808            sb.append(" low RAM for ");
10809            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10810            Slog.i(TAG, sb.toString());
10811
10812            // If at least 1/3 of our time since the last idle period has been spent
10813            // with RAM low, then we want to kill processes.
10814            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10815
10816            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10817                ProcessRecord proc = mLruProcesses.get(i);
10818                if (proc.notCachedSinceIdle) {
10819                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10820                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10821                        if (doKilling && proc.initialIdlePss != 0
10822                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10823                            proc.kill("idle maint (pss " + proc.lastPss
10824                                    + " from " + proc.initialIdlePss + ")", true);
10825                        }
10826                    }
10827                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10828                    proc.notCachedSinceIdle = true;
10829                    proc.initialIdlePss = 0;
10830                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10831                            isSleeping(), now);
10832                }
10833            }
10834
10835            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10836            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10837        }
10838    }
10839
10840    private void retrieveSettings() {
10841        final ContentResolver resolver = mContext.getContentResolver();
10842        String debugApp = Settings.Global.getString(
10843            resolver, Settings.Global.DEBUG_APP);
10844        boolean waitForDebugger = Settings.Global.getInt(
10845            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10846        boolean alwaysFinishActivities = Settings.Global.getInt(
10847            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10848        boolean forceRtl = Settings.Global.getInt(
10849                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10850        // Transfer any global setting for forcing RTL layout, into a System Property
10851        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10852
10853        Configuration configuration = new Configuration();
10854        Settings.System.getConfiguration(resolver, configuration);
10855        if (forceRtl) {
10856            // This will take care of setting the correct layout direction flags
10857            configuration.setLayoutDirection(configuration.locale);
10858        }
10859
10860        synchronized (this) {
10861            mDebugApp = mOrigDebugApp = debugApp;
10862            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10863            mAlwaysFinishActivities = alwaysFinishActivities;
10864            // This happens before any activities are started, so we can
10865            // change mConfiguration in-place.
10866            updateConfigurationLocked(configuration, null, false, true);
10867            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10868        }
10869    }
10870
10871    /** Loads resources after the current configuration has been set. */
10872    private void loadResourcesOnSystemReady() {
10873        final Resources res = mContext.getResources();
10874        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10875        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10876        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10877    }
10878
10879    public boolean testIsSystemReady() {
10880        // no need to synchronize(this) just to read & return the value
10881        return mSystemReady;
10882    }
10883
10884    private static File getCalledPreBootReceiversFile() {
10885        File dataDir = Environment.getDataDirectory();
10886        File systemDir = new File(dataDir, "system");
10887        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10888        return fname;
10889    }
10890
10891    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10892        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10893        File file = getCalledPreBootReceiversFile();
10894        FileInputStream fis = null;
10895        try {
10896            fis = new FileInputStream(file);
10897            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10898            int fvers = dis.readInt();
10899            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10900                String vers = dis.readUTF();
10901                String codename = dis.readUTF();
10902                String build = dis.readUTF();
10903                if (android.os.Build.VERSION.RELEASE.equals(vers)
10904                        && android.os.Build.VERSION.CODENAME.equals(codename)
10905                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10906                    int num = dis.readInt();
10907                    while (num > 0) {
10908                        num--;
10909                        String pkg = dis.readUTF();
10910                        String cls = dis.readUTF();
10911                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10912                    }
10913                }
10914            }
10915        } catch (FileNotFoundException e) {
10916        } catch (IOException e) {
10917            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10918        } finally {
10919            if (fis != null) {
10920                try {
10921                    fis.close();
10922                } catch (IOException e) {
10923                }
10924            }
10925        }
10926        return lastDoneReceivers;
10927    }
10928
10929    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10930        File file = getCalledPreBootReceiversFile();
10931        FileOutputStream fos = null;
10932        DataOutputStream dos = null;
10933        try {
10934            fos = new FileOutputStream(file);
10935            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10936            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10937            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10938            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10939            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10940            dos.writeInt(list.size());
10941            for (int i=0; i<list.size(); i++) {
10942                dos.writeUTF(list.get(i).getPackageName());
10943                dos.writeUTF(list.get(i).getClassName());
10944            }
10945        } catch (IOException e) {
10946            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10947            file.delete();
10948        } finally {
10949            FileUtils.sync(fos);
10950            if (dos != null) {
10951                try {
10952                    dos.close();
10953                } catch (IOException e) {
10954                    // TODO Auto-generated catch block
10955                    e.printStackTrace();
10956                }
10957            }
10958        }
10959    }
10960
10961    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10962            ArrayList<ComponentName> doneReceivers, int userId) {
10963        boolean waitingUpdate = false;
10964        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10965        List<ResolveInfo> ris = null;
10966        try {
10967            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10968                    intent, null, 0, userId);
10969        } catch (RemoteException e) {
10970        }
10971        if (ris != null) {
10972            for (int i=ris.size()-1; i>=0; i--) {
10973                if ((ris.get(i).activityInfo.applicationInfo.flags
10974                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10975                    ris.remove(i);
10976                }
10977            }
10978            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10979
10980            // For User 0, load the version number. When delivering to a new user, deliver
10981            // to all receivers.
10982            if (userId == UserHandle.USER_OWNER) {
10983                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10984                for (int i=0; i<ris.size(); i++) {
10985                    ActivityInfo ai = ris.get(i).activityInfo;
10986                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10987                    if (lastDoneReceivers.contains(comp)) {
10988                        // We already did the pre boot receiver for this app with the current
10989                        // platform version, so don't do it again...
10990                        ris.remove(i);
10991                        i--;
10992                        // ...however, do keep it as one that has been done, so we don't
10993                        // forget about it when rewriting the file of last done receivers.
10994                        doneReceivers.add(comp);
10995                    }
10996                }
10997            }
10998
10999            // If primary user, send broadcast to all available users, else just to userId
11000            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11001                    : new int[] { userId };
11002            for (int i = 0; i < ris.size(); i++) {
11003                ActivityInfo ai = ris.get(i).activityInfo;
11004                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11005                doneReceivers.add(comp);
11006                intent.setComponent(comp);
11007                for (int j=0; j<users.length; j++) {
11008                    IIntentReceiver finisher = null;
11009                    // On last receiver and user, set up a completion callback
11010                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11011                        finisher = new IIntentReceiver.Stub() {
11012                            public void performReceive(Intent intent, int resultCode,
11013                                    String data, Bundle extras, boolean ordered,
11014                                    boolean sticky, int sendingUser) {
11015                                // The raw IIntentReceiver interface is called
11016                                // with the AM lock held, so redispatch to
11017                                // execute our code without the lock.
11018                                mHandler.post(onFinishCallback);
11019                            }
11020                        };
11021                    }
11022                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11023                            + " for user " + users[j]);
11024                    broadcastIntentLocked(null, null, intent, null, finisher,
11025                            0, null, null, null, AppOpsManager.OP_NONE,
11026                            true, false, MY_PID, Process.SYSTEM_UID,
11027                            users[j]);
11028                    if (finisher != null) {
11029                        waitingUpdate = true;
11030                    }
11031                }
11032            }
11033        }
11034
11035        return waitingUpdate;
11036    }
11037
11038    public void systemReady(final Runnable goingCallback) {
11039        synchronized(this) {
11040            if (mSystemReady) {
11041                // If we're done calling all the receivers, run the next "boot phase" passed in
11042                // by the SystemServer
11043                if (goingCallback != null) {
11044                    goingCallback.run();
11045                }
11046                return;
11047            }
11048
11049            // Make sure we have the current profile info, since it is needed for
11050            // security checks.
11051            updateCurrentProfileIdsLocked();
11052
11053            if (mRecentTasks == null) {
11054                mRecentTasks = mTaskPersister.restoreTasksLocked();
11055                if (!mRecentTasks.isEmpty()) {
11056                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11057                }
11058                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11059                mTaskPersister.startPersisting();
11060            }
11061
11062            // Check to see if there are any update receivers to run.
11063            if (!mDidUpdate) {
11064                if (mWaitingUpdate) {
11065                    return;
11066                }
11067                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11068                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11069                    public void run() {
11070                        synchronized (ActivityManagerService.this) {
11071                            mDidUpdate = true;
11072                        }
11073                        writeLastDonePreBootReceivers(doneReceivers);
11074                        showBootMessage(mContext.getText(
11075                                R.string.android_upgrading_complete),
11076                                false);
11077                        systemReady(goingCallback);
11078                    }
11079                }, doneReceivers, UserHandle.USER_OWNER);
11080
11081                if (mWaitingUpdate) {
11082                    return;
11083                }
11084                mDidUpdate = true;
11085            }
11086
11087            mAppOpsService.systemReady();
11088            mSystemReady = true;
11089        }
11090
11091        ArrayList<ProcessRecord> procsToKill = null;
11092        synchronized(mPidsSelfLocked) {
11093            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11094                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11095                if (!isAllowedWhileBooting(proc.info)){
11096                    if (procsToKill == null) {
11097                        procsToKill = new ArrayList<ProcessRecord>();
11098                    }
11099                    procsToKill.add(proc);
11100                }
11101            }
11102        }
11103
11104        synchronized(this) {
11105            if (procsToKill != null) {
11106                for (int i=procsToKill.size()-1; i>=0; i--) {
11107                    ProcessRecord proc = procsToKill.get(i);
11108                    Slog.i(TAG, "Removing system update proc: " + proc);
11109                    removeProcessLocked(proc, true, false, "system update done");
11110                }
11111            }
11112
11113            // Now that we have cleaned up any update processes, we
11114            // are ready to start launching real processes and know that
11115            // we won't trample on them any more.
11116            mProcessesReady = true;
11117        }
11118
11119        Slog.i(TAG, "System now ready");
11120        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11121            SystemClock.uptimeMillis());
11122
11123        synchronized(this) {
11124            // Make sure we have no pre-ready processes sitting around.
11125
11126            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11127                ResolveInfo ri = mContext.getPackageManager()
11128                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11129                                STOCK_PM_FLAGS);
11130                CharSequence errorMsg = null;
11131                if (ri != null) {
11132                    ActivityInfo ai = ri.activityInfo;
11133                    ApplicationInfo app = ai.applicationInfo;
11134                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11135                        mTopAction = Intent.ACTION_FACTORY_TEST;
11136                        mTopData = null;
11137                        mTopComponent = new ComponentName(app.packageName,
11138                                ai.name);
11139                    } else {
11140                        errorMsg = mContext.getResources().getText(
11141                                com.android.internal.R.string.factorytest_not_system);
11142                    }
11143                } else {
11144                    errorMsg = mContext.getResources().getText(
11145                            com.android.internal.R.string.factorytest_no_action);
11146                }
11147                if (errorMsg != null) {
11148                    mTopAction = null;
11149                    mTopData = null;
11150                    mTopComponent = null;
11151                    Message msg = Message.obtain();
11152                    msg.what = SHOW_FACTORY_ERROR_MSG;
11153                    msg.getData().putCharSequence("msg", errorMsg);
11154                    mHandler.sendMessage(msg);
11155                }
11156            }
11157        }
11158
11159        retrieveSettings();
11160        loadResourcesOnSystemReady();
11161
11162        synchronized (this) {
11163            readGrantedUriPermissionsLocked();
11164        }
11165
11166        if (goingCallback != null) goingCallback.run();
11167
11168        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11169                Integer.toString(mCurrentUserId), mCurrentUserId);
11170        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11171                Integer.toString(mCurrentUserId), mCurrentUserId);
11172        mSystemServiceManager.startUser(mCurrentUserId);
11173
11174        synchronized (this) {
11175            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11176                try {
11177                    List apps = AppGlobals.getPackageManager().
11178                        getPersistentApplications(STOCK_PM_FLAGS);
11179                    if (apps != null) {
11180                        int N = apps.size();
11181                        int i;
11182                        for (i=0; i<N; i++) {
11183                            ApplicationInfo info
11184                                = (ApplicationInfo)apps.get(i);
11185                            if (info != null &&
11186                                    !info.packageName.equals("android")) {
11187                                addAppLocked(info, false, null /* ABI override */);
11188                            }
11189                        }
11190                    }
11191                } catch (RemoteException ex) {
11192                    // pm is in same process, this will never happen.
11193                }
11194            }
11195
11196            // Start up initial activity.
11197            mBooting = true;
11198
11199            try {
11200                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11201                    Message msg = Message.obtain();
11202                    msg.what = SHOW_UID_ERROR_MSG;
11203                    mHandler.sendMessage(msg);
11204                }
11205            } catch (RemoteException e) {
11206            }
11207
11208            long ident = Binder.clearCallingIdentity();
11209            try {
11210                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11211                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11212                        | Intent.FLAG_RECEIVER_FOREGROUND);
11213                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11214                broadcastIntentLocked(null, null, intent,
11215                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11216                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11217                intent = new Intent(Intent.ACTION_USER_STARTING);
11218                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11219                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11220                broadcastIntentLocked(null, null, intent,
11221                        null, new IIntentReceiver.Stub() {
11222                            @Override
11223                            public void performReceive(Intent intent, int resultCode, String data,
11224                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11225                                    throws RemoteException {
11226                            }
11227                        }, 0, null, null,
11228                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11229                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11230            } catch (Throwable t) {
11231                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11232            } finally {
11233                Binder.restoreCallingIdentity(ident);
11234            }
11235            mStackSupervisor.resumeTopActivitiesLocked();
11236            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11237        }
11238    }
11239
11240    private boolean makeAppCrashingLocked(ProcessRecord app,
11241            String shortMsg, String longMsg, String stackTrace) {
11242        app.crashing = true;
11243        app.crashingReport = generateProcessError(app,
11244                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11245        startAppProblemLocked(app);
11246        app.stopFreezingAllLocked();
11247        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11248    }
11249
11250    private void makeAppNotRespondingLocked(ProcessRecord app,
11251            String activity, String shortMsg, String longMsg) {
11252        app.notResponding = true;
11253        app.notRespondingReport = generateProcessError(app,
11254                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11255                activity, shortMsg, longMsg, null);
11256        startAppProblemLocked(app);
11257        app.stopFreezingAllLocked();
11258    }
11259
11260    /**
11261     * Generate a process error record, suitable for attachment to a ProcessRecord.
11262     *
11263     * @param app The ProcessRecord in which the error occurred.
11264     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11265     *                      ActivityManager.AppErrorStateInfo
11266     * @param activity The activity associated with the crash, if known.
11267     * @param shortMsg Short message describing the crash.
11268     * @param longMsg Long message describing the crash.
11269     * @param stackTrace Full crash stack trace, may be null.
11270     *
11271     * @return Returns a fully-formed AppErrorStateInfo record.
11272     */
11273    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11274            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11275        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11276
11277        report.condition = condition;
11278        report.processName = app.processName;
11279        report.pid = app.pid;
11280        report.uid = app.info.uid;
11281        report.tag = activity;
11282        report.shortMsg = shortMsg;
11283        report.longMsg = longMsg;
11284        report.stackTrace = stackTrace;
11285
11286        return report;
11287    }
11288
11289    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11290        synchronized (this) {
11291            app.crashing = false;
11292            app.crashingReport = null;
11293            app.notResponding = false;
11294            app.notRespondingReport = null;
11295            if (app.anrDialog == fromDialog) {
11296                app.anrDialog = null;
11297            }
11298            if (app.waitDialog == fromDialog) {
11299                app.waitDialog = null;
11300            }
11301            if (app.pid > 0 && app.pid != MY_PID) {
11302                handleAppCrashLocked(app, null, null, null);
11303                app.kill("user request after error", true);
11304            }
11305        }
11306    }
11307
11308    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11309            String stackTrace) {
11310        long now = SystemClock.uptimeMillis();
11311
11312        Long crashTime;
11313        if (!app.isolated) {
11314            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11315        } else {
11316            crashTime = null;
11317        }
11318        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11319            // This process loses!
11320            Slog.w(TAG, "Process " + app.info.processName
11321                    + " has crashed too many times: killing!");
11322            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11323                    app.userId, app.info.processName, app.uid);
11324            mStackSupervisor.handleAppCrashLocked(app);
11325            if (!app.persistent) {
11326                // We don't want to start this process again until the user
11327                // explicitly does so...  but for persistent process, we really
11328                // need to keep it running.  If a persistent process is actually
11329                // repeatedly crashing, then badness for everyone.
11330                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11331                        app.info.processName);
11332                if (!app.isolated) {
11333                    // XXX We don't have a way to mark isolated processes
11334                    // as bad, since they don't have a peristent identity.
11335                    mBadProcesses.put(app.info.processName, app.uid,
11336                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11337                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11338                }
11339                app.bad = true;
11340                app.removed = true;
11341                // Don't let services in this process be restarted and potentially
11342                // annoy the user repeatedly.  Unless it is persistent, since those
11343                // processes run critical code.
11344                removeProcessLocked(app, false, false, "crash");
11345                mStackSupervisor.resumeTopActivitiesLocked();
11346                return false;
11347            }
11348            mStackSupervisor.resumeTopActivitiesLocked();
11349        } else {
11350            mStackSupervisor.finishTopRunningActivityLocked(app);
11351        }
11352
11353        // Bump up the crash count of any services currently running in the proc.
11354        for (int i=app.services.size()-1; i>=0; i--) {
11355            // Any services running in the application need to be placed
11356            // back in the pending list.
11357            ServiceRecord sr = app.services.valueAt(i);
11358            sr.crashCount++;
11359        }
11360
11361        // If the crashing process is what we consider to be the "home process" and it has been
11362        // replaced by a third-party app, clear the package preferred activities from packages
11363        // with a home activity running in the process to prevent a repeatedly crashing app
11364        // from blocking the user to manually clear the list.
11365        final ArrayList<ActivityRecord> activities = app.activities;
11366        if (app == mHomeProcess && activities.size() > 0
11367                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11368            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11369                final ActivityRecord r = activities.get(activityNdx);
11370                if (r.isHomeActivity()) {
11371                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11372                    try {
11373                        ActivityThread.getPackageManager()
11374                                .clearPackagePreferredActivities(r.packageName);
11375                    } catch (RemoteException c) {
11376                        // pm is in same process, this will never happen.
11377                    }
11378                }
11379            }
11380        }
11381
11382        if (!app.isolated) {
11383            // XXX Can't keep track of crash times for isolated processes,
11384            // because they don't have a perisistent identity.
11385            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11386        }
11387
11388        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11389        return true;
11390    }
11391
11392    void startAppProblemLocked(ProcessRecord app) {
11393        // If this app is not running under the current user, then we
11394        // can't give it a report button because that would require
11395        // launching the report UI under a different user.
11396        app.errorReportReceiver = null;
11397
11398        for (int userId : mCurrentProfileIds) {
11399            if (app.userId == userId) {
11400                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11401                        mContext, app.info.packageName, app.info.flags);
11402            }
11403        }
11404        skipCurrentReceiverLocked(app);
11405    }
11406
11407    void skipCurrentReceiverLocked(ProcessRecord app) {
11408        for (BroadcastQueue queue : mBroadcastQueues) {
11409            queue.skipCurrentReceiverLocked(app);
11410        }
11411    }
11412
11413    /**
11414     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11415     * The application process will exit immediately after this call returns.
11416     * @param app object of the crashing app, null for the system server
11417     * @param crashInfo describing the exception
11418     */
11419    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11420        ProcessRecord r = findAppProcess(app, "Crash");
11421        final String processName = app == null ? "system_server"
11422                : (r == null ? "unknown" : r.processName);
11423
11424        handleApplicationCrashInner("crash", r, processName, crashInfo);
11425    }
11426
11427    /* Native crash reporting uses this inner version because it needs to be somewhat
11428     * decoupled from the AM-managed cleanup lifecycle
11429     */
11430    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11431            ApplicationErrorReport.CrashInfo crashInfo) {
11432        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11433                UserHandle.getUserId(Binder.getCallingUid()), processName,
11434                r == null ? -1 : r.info.flags,
11435                crashInfo.exceptionClassName,
11436                crashInfo.exceptionMessage,
11437                crashInfo.throwFileName,
11438                crashInfo.throwLineNumber);
11439
11440        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11441
11442        crashApplication(r, crashInfo);
11443    }
11444
11445    public void handleApplicationStrictModeViolation(
11446            IBinder app,
11447            int violationMask,
11448            StrictMode.ViolationInfo info) {
11449        ProcessRecord r = findAppProcess(app, "StrictMode");
11450        if (r == null) {
11451            return;
11452        }
11453
11454        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11455            Integer stackFingerprint = info.hashCode();
11456            boolean logIt = true;
11457            synchronized (mAlreadyLoggedViolatedStacks) {
11458                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11459                    logIt = false;
11460                    // TODO: sub-sample into EventLog for these, with
11461                    // the info.durationMillis?  Then we'd get
11462                    // the relative pain numbers, without logging all
11463                    // the stack traces repeatedly.  We'd want to do
11464                    // likewise in the client code, which also does
11465                    // dup suppression, before the Binder call.
11466                } else {
11467                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11468                        mAlreadyLoggedViolatedStacks.clear();
11469                    }
11470                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11471                }
11472            }
11473            if (logIt) {
11474                logStrictModeViolationToDropBox(r, info);
11475            }
11476        }
11477
11478        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11479            AppErrorResult result = new AppErrorResult();
11480            synchronized (this) {
11481                final long origId = Binder.clearCallingIdentity();
11482
11483                Message msg = Message.obtain();
11484                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11485                HashMap<String, Object> data = new HashMap<String, Object>();
11486                data.put("result", result);
11487                data.put("app", r);
11488                data.put("violationMask", violationMask);
11489                data.put("info", info);
11490                msg.obj = data;
11491                mHandler.sendMessage(msg);
11492
11493                Binder.restoreCallingIdentity(origId);
11494            }
11495            int res = result.get();
11496            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11497        }
11498    }
11499
11500    // Depending on the policy in effect, there could be a bunch of
11501    // these in quick succession so we try to batch these together to
11502    // minimize disk writes, number of dropbox entries, and maximize
11503    // compression, by having more fewer, larger records.
11504    private void logStrictModeViolationToDropBox(
11505            ProcessRecord process,
11506            StrictMode.ViolationInfo info) {
11507        if (info == null) {
11508            return;
11509        }
11510        final boolean isSystemApp = process == null ||
11511                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11512                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11513        final String processName = process == null ? "unknown" : process.processName;
11514        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11515        final DropBoxManager dbox = (DropBoxManager)
11516                mContext.getSystemService(Context.DROPBOX_SERVICE);
11517
11518        // Exit early if the dropbox isn't configured to accept this report type.
11519        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11520
11521        boolean bufferWasEmpty;
11522        boolean needsFlush;
11523        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11524        synchronized (sb) {
11525            bufferWasEmpty = sb.length() == 0;
11526            appendDropBoxProcessHeaders(process, processName, sb);
11527            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11528            sb.append("System-App: ").append(isSystemApp).append("\n");
11529            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11530            if (info.violationNumThisLoop != 0) {
11531                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11532            }
11533            if (info.numAnimationsRunning != 0) {
11534                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11535            }
11536            if (info.broadcastIntentAction != null) {
11537                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11538            }
11539            if (info.durationMillis != -1) {
11540                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11541            }
11542            if (info.numInstances != -1) {
11543                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11544            }
11545            if (info.tags != null) {
11546                for (String tag : info.tags) {
11547                    sb.append("Span-Tag: ").append(tag).append("\n");
11548                }
11549            }
11550            sb.append("\n");
11551            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11552                sb.append(info.crashInfo.stackTrace);
11553            }
11554            sb.append("\n");
11555
11556            // Only buffer up to ~64k.  Various logging bits truncate
11557            // things at 128k.
11558            needsFlush = (sb.length() > 64 * 1024);
11559        }
11560
11561        // Flush immediately if the buffer's grown too large, or this
11562        // is a non-system app.  Non-system apps are isolated with a
11563        // different tag & policy and not batched.
11564        //
11565        // Batching is useful during internal testing with
11566        // StrictMode settings turned up high.  Without batching,
11567        // thousands of separate files could be created on boot.
11568        if (!isSystemApp || needsFlush) {
11569            new Thread("Error dump: " + dropboxTag) {
11570                @Override
11571                public void run() {
11572                    String report;
11573                    synchronized (sb) {
11574                        report = sb.toString();
11575                        sb.delete(0, sb.length());
11576                        sb.trimToSize();
11577                    }
11578                    if (report.length() != 0) {
11579                        dbox.addText(dropboxTag, report);
11580                    }
11581                }
11582            }.start();
11583            return;
11584        }
11585
11586        // System app batching:
11587        if (!bufferWasEmpty) {
11588            // An existing dropbox-writing thread is outstanding, so
11589            // we don't need to start it up.  The existing thread will
11590            // catch the buffer appends we just did.
11591            return;
11592        }
11593
11594        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11595        // (After this point, we shouldn't access AMS internal data structures.)
11596        new Thread("Error dump: " + dropboxTag) {
11597            @Override
11598            public void run() {
11599                // 5 second sleep to let stacks arrive and be batched together
11600                try {
11601                    Thread.sleep(5000);  // 5 seconds
11602                } catch (InterruptedException e) {}
11603
11604                String errorReport;
11605                synchronized (mStrictModeBuffer) {
11606                    errorReport = mStrictModeBuffer.toString();
11607                    if (errorReport.length() == 0) {
11608                        return;
11609                    }
11610                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11611                    mStrictModeBuffer.trimToSize();
11612                }
11613                dbox.addText(dropboxTag, errorReport);
11614            }
11615        }.start();
11616    }
11617
11618    /**
11619     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11620     * @param app object of the crashing app, null for the system server
11621     * @param tag reported by the caller
11622     * @param system whether this wtf is coming from the system
11623     * @param crashInfo describing the context of the error
11624     * @return true if the process should exit immediately (WTF is fatal)
11625     */
11626    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11627            final ApplicationErrorReport.CrashInfo crashInfo) {
11628        final ProcessRecord r = findAppProcess(app, "WTF");
11629        final String processName = app == null ? "system_server"
11630                : (r == null ? "unknown" : r.processName);
11631
11632        EventLog.writeEvent(EventLogTags.AM_WTF,
11633                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11634                processName,
11635                r == null ? -1 : r.info.flags,
11636                tag, crashInfo.exceptionMessage);
11637
11638        if (system) {
11639            // If this is coming from the system, we could very well have low-level
11640            // system locks held, so we want to do this all asynchronously.  And we
11641            // never want this to become fatal, so there is that too.
11642            mHandler.post(new Runnable() {
11643                @Override public void run() {
11644                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11645                            crashInfo);
11646                }
11647            });
11648            return false;
11649        }
11650
11651        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11652
11653        if (r != null && r.pid != Process.myPid() &&
11654                Settings.Global.getInt(mContext.getContentResolver(),
11655                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11656            crashApplication(r, crashInfo);
11657            return true;
11658        } else {
11659            return false;
11660        }
11661    }
11662
11663    /**
11664     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11665     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11666     */
11667    private ProcessRecord findAppProcess(IBinder app, String reason) {
11668        if (app == null) {
11669            return null;
11670        }
11671
11672        synchronized (this) {
11673            final int NP = mProcessNames.getMap().size();
11674            for (int ip=0; ip<NP; ip++) {
11675                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11676                final int NA = apps.size();
11677                for (int ia=0; ia<NA; ia++) {
11678                    ProcessRecord p = apps.valueAt(ia);
11679                    if (p.thread != null && p.thread.asBinder() == app) {
11680                        return p;
11681                    }
11682                }
11683            }
11684
11685            Slog.w(TAG, "Can't find mystery application for " + reason
11686                    + " from pid=" + Binder.getCallingPid()
11687                    + " uid=" + Binder.getCallingUid() + ": " + app);
11688            return null;
11689        }
11690    }
11691
11692    /**
11693     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11694     * to append various headers to the dropbox log text.
11695     */
11696    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11697            StringBuilder sb) {
11698        // Watchdog thread ends up invoking this function (with
11699        // a null ProcessRecord) to add the stack file to dropbox.
11700        // Do not acquire a lock on this (am) in such cases, as it
11701        // could cause a potential deadlock, if and when watchdog
11702        // is invoked due to unavailability of lock on am and it
11703        // would prevent watchdog from killing system_server.
11704        if (process == null) {
11705            sb.append("Process: ").append(processName).append("\n");
11706            return;
11707        }
11708        // Note: ProcessRecord 'process' is guarded by the service
11709        // instance.  (notably process.pkgList, which could otherwise change
11710        // concurrently during execution of this method)
11711        synchronized (this) {
11712            sb.append("Process: ").append(processName).append("\n");
11713            int flags = process.info.flags;
11714            IPackageManager pm = AppGlobals.getPackageManager();
11715            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11716            for (int ip=0; ip<process.pkgList.size(); ip++) {
11717                String pkg = process.pkgList.keyAt(ip);
11718                sb.append("Package: ").append(pkg);
11719                try {
11720                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11721                    if (pi != null) {
11722                        sb.append(" v").append(pi.versionCode);
11723                        if (pi.versionName != null) {
11724                            sb.append(" (").append(pi.versionName).append(")");
11725                        }
11726                    }
11727                } catch (RemoteException e) {
11728                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11729                }
11730                sb.append("\n");
11731            }
11732        }
11733    }
11734
11735    private static String processClass(ProcessRecord process) {
11736        if (process == null || process.pid == MY_PID) {
11737            return "system_server";
11738        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11739            return "system_app";
11740        } else {
11741            return "data_app";
11742        }
11743    }
11744
11745    /**
11746     * Write a description of an error (crash, WTF, ANR) to the drop box.
11747     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11748     * @param process which caused the error, null means the system server
11749     * @param activity which triggered the error, null if unknown
11750     * @param parent activity related to the error, null if unknown
11751     * @param subject line related to the error, null if absent
11752     * @param report in long form describing the error, null if absent
11753     * @param logFile to include in the report, null if none
11754     * @param crashInfo giving an application stack trace, null if absent
11755     */
11756    public void addErrorToDropBox(String eventType,
11757            ProcessRecord process, String processName, ActivityRecord activity,
11758            ActivityRecord parent, String subject,
11759            final String report, final File logFile,
11760            final ApplicationErrorReport.CrashInfo crashInfo) {
11761        // NOTE -- this must never acquire the ActivityManagerService lock,
11762        // otherwise the watchdog may be prevented from resetting the system.
11763
11764        final String dropboxTag = processClass(process) + "_" + eventType;
11765        final DropBoxManager dbox = (DropBoxManager)
11766                mContext.getSystemService(Context.DROPBOX_SERVICE);
11767
11768        // Exit early if the dropbox isn't configured to accept this report type.
11769        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11770
11771        final StringBuilder sb = new StringBuilder(1024);
11772        appendDropBoxProcessHeaders(process, processName, sb);
11773        if (activity != null) {
11774            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11775        }
11776        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11777            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11778        }
11779        if (parent != null && parent != activity) {
11780            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11781        }
11782        if (subject != null) {
11783            sb.append("Subject: ").append(subject).append("\n");
11784        }
11785        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11786        if (Debug.isDebuggerConnected()) {
11787            sb.append("Debugger: Connected\n");
11788        }
11789        sb.append("\n");
11790
11791        // Do the rest in a worker thread to avoid blocking the caller on I/O
11792        // (After this point, we shouldn't access AMS internal data structures.)
11793        Thread worker = new Thread("Error dump: " + dropboxTag) {
11794            @Override
11795            public void run() {
11796                if (report != null) {
11797                    sb.append(report);
11798                }
11799                if (logFile != null) {
11800                    try {
11801                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11802                                    "\n\n[[TRUNCATED]]"));
11803                    } catch (IOException e) {
11804                        Slog.e(TAG, "Error reading " + logFile, e);
11805                    }
11806                }
11807                if (crashInfo != null && crashInfo.stackTrace != null) {
11808                    sb.append(crashInfo.stackTrace);
11809                }
11810
11811                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11812                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11813                if (lines > 0) {
11814                    sb.append("\n");
11815
11816                    // Merge several logcat streams, and take the last N lines
11817                    InputStreamReader input = null;
11818                    try {
11819                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11820                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11821                                "-b", "crash",
11822                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11823
11824                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11825                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11826                        input = new InputStreamReader(logcat.getInputStream());
11827
11828                        int num;
11829                        char[] buf = new char[8192];
11830                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11831                    } catch (IOException e) {
11832                        Slog.e(TAG, "Error running logcat", e);
11833                    } finally {
11834                        if (input != null) try { input.close(); } catch (IOException e) {}
11835                    }
11836                }
11837
11838                dbox.addText(dropboxTag, sb.toString());
11839            }
11840        };
11841
11842        if (process == null) {
11843            // If process is null, we are being called from some internal code
11844            // and may be about to die -- run this synchronously.
11845            worker.run();
11846        } else {
11847            worker.start();
11848        }
11849    }
11850
11851    /**
11852     * Bring up the "unexpected error" dialog box for a crashing app.
11853     * Deal with edge cases (intercepts from instrumented applications,
11854     * ActivityController, error intent receivers, that sort of thing).
11855     * @param r the application crashing
11856     * @param crashInfo describing the failure
11857     */
11858    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11859        long timeMillis = System.currentTimeMillis();
11860        String shortMsg = crashInfo.exceptionClassName;
11861        String longMsg = crashInfo.exceptionMessage;
11862        String stackTrace = crashInfo.stackTrace;
11863        if (shortMsg != null && longMsg != null) {
11864            longMsg = shortMsg + ": " + longMsg;
11865        } else if (shortMsg != null) {
11866            longMsg = shortMsg;
11867        }
11868
11869        AppErrorResult result = new AppErrorResult();
11870        synchronized (this) {
11871            if (mController != null) {
11872                try {
11873                    String name = r != null ? r.processName : null;
11874                    int pid = r != null ? r.pid : Binder.getCallingPid();
11875                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11876                    if (!mController.appCrashed(name, pid,
11877                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11878                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11879                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11880                            Slog.w(TAG, "Skip killing native crashed app " + name
11881                                    + "(" + pid + ") during testing");
11882                        } else {
11883                            Slog.w(TAG, "Force-killing crashed app " + name
11884                                    + " at watcher's request");
11885                            if (r != null) {
11886                                r.kill("crash", true);
11887                            } else {
11888                                // Huh.
11889                                Process.killProcess(pid);
11890                                Process.killProcessGroup(uid, pid);
11891                            }
11892                        }
11893                        return;
11894                    }
11895                } catch (RemoteException e) {
11896                    mController = null;
11897                    Watchdog.getInstance().setActivityController(null);
11898                }
11899            }
11900
11901            final long origId = Binder.clearCallingIdentity();
11902
11903            // If this process is running instrumentation, finish it.
11904            if (r != null && r.instrumentationClass != null) {
11905                Slog.w(TAG, "Error in app " + r.processName
11906                      + " running instrumentation " + r.instrumentationClass + ":");
11907                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11908                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11909                Bundle info = new Bundle();
11910                info.putString("shortMsg", shortMsg);
11911                info.putString("longMsg", longMsg);
11912                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11913                Binder.restoreCallingIdentity(origId);
11914                return;
11915            }
11916
11917            // If we can't identify the process or it's already exceeded its crash quota,
11918            // quit right away without showing a crash dialog.
11919            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11920                Binder.restoreCallingIdentity(origId);
11921                return;
11922            }
11923
11924            Message msg = Message.obtain();
11925            msg.what = SHOW_ERROR_MSG;
11926            HashMap data = new HashMap();
11927            data.put("result", result);
11928            data.put("app", r);
11929            msg.obj = data;
11930            mHandler.sendMessage(msg);
11931
11932            Binder.restoreCallingIdentity(origId);
11933        }
11934
11935        int res = result.get();
11936
11937        Intent appErrorIntent = null;
11938        synchronized (this) {
11939            if (r != null && !r.isolated) {
11940                // XXX Can't keep track of crash time for isolated processes,
11941                // since they don't have a persistent identity.
11942                mProcessCrashTimes.put(r.info.processName, r.uid,
11943                        SystemClock.uptimeMillis());
11944            }
11945            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11946                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11947            }
11948        }
11949
11950        if (appErrorIntent != null) {
11951            try {
11952                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11953            } catch (ActivityNotFoundException e) {
11954                Slog.w(TAG, "bug report receiver dissappeared", e);
11955            }
11956        }
11957    }
11958
11959    Intent createAppErrorIntentLocked(ProcessRecord r,
11960            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11961        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11962        if (report == null) {
11963            return null;
11964        }
11965        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11966        result.setComponent(r.errorReportReceiver);
11967        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11968        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11969        return result;
11970    }
11971
11972    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11973            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11974        if (r.errorReportReceiver == null) {
11975            return null;
11976        }
11977
11978        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11979            return null;
11980        }
11981
11982        ApplicationErrorReport report = new ApplicationErrorReport();
11983        report.packageName = r.info.packageName;
11984        report.installerPackageName = r.errorReportReceiver.getPackageName();
11985        report.processName = r.processName;
11986        report.time = timeMillis;
11987        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11988
11989        if (r.crashing || r.forceCrashReport) {
11990            report.type = ApplicationErrorReport.TYPE_CRASH;
11991            report.crashInfo = crashInfo;
11992        } else if (r.notResponding) {
11993            report.type = ApplicationErrorReport.TYPE_ANR;
11994            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11995
11996            report.anrInfo.activity = r.notRespondingReport.tag;
11997            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11998            report.anrInfo.info = r.notRespondingReport.longMsg;
11999        }
12000
12001        return report;
12002    }
12003
12004    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12005        enforceNotIsolatedCaller("getProcessesInErrorState");
12006        // assume our apps are happy - lazy create the list
12007        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12008
12009        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12010                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12011        int userId = UserHandle.getUserId(Binder.getCallingUid());
12012
12013        synchronized (this) {
12014
12015            // iterate across all processes
12016            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12017                ProcessRecord app = mLruProcesses.get(i);
12018                if (!allUsers && app.userId != userId) {
12019                    continue;
12020                }
12021                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12022                    // This one's in trouble, so we'll generate a report for it
12023                    // crashes are higher priority (in case there's a crash *and* an anr)
12024                    ActivityManager.ProcessErrorStateInfo report = null;
12025                    if (app.crashing) {
12026                        report = app.crashingReport;
12027                    } else if (app.notResponding) {
12028                        report = app.notRespondingReport;
12029                    }
12030
12031                    if (report != null) {
12032                        if (errList == null) {
12033                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12034                        }
12035                        errList.add(report);
12036                    } else {
12037                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12038                                " crashing = " + app.crashing +
12039                                " notResponding = " + app.notResponding);
12040                    }
12041                }
12042            }
12043        }
12044
12045        return errList;
12046    }
12047
12048    static int procStateToImportance(int procState, int memAdj,
12049            ActivityManager.RunningAppProcessInfo currApp) {
12050        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12051        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12052            currApp.lru = memAdj;
12053        } else {
12054            currApp.lru = 0;
12055        }
12056        return imp;
12057    }
12058
12059    private void fillInProcMemInfo(ProcessRecord app,
12060            ActivityManager.RunningAppProcessInfo outInfo) {
12061        outInfo.pid = app.pid;
12062        outInfo.uid = app.info.uid;
12063        if (mHeavyWeightProcess == app) {
12064            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12065        }
12066        if (app.persistent) {
12067            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12068        }
12069        if (app.activities.size() > 0) {
12070            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12071        }
12072        outInfo.lastTrimLevel = app.trimMemoryLevel;
12073        int adj = app.curAdj;
12074        int procState = app.curProcState;
12075        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12076        outInfo.importanceReasonCode = app.adjTypeCode;
12077        outInfo.processState = app.curProcState;
12078    }
12079
12080    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12081        enforceNotIsolatedCaller("getRunningAppProcesses");
12082        // Lazy instantiation of list
12083        List<ActivityManager.RunningAppProcessInfo> runList = null;
12084        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12085                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12086        int userId = UserHandle.getUserId(Binder.getCallingUid());
12087        synchronized (this) {
12088            // Iterate across all processes
12089            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12090                ProcessRecord app = mLruProcesses.get(i);
12091                if (!allUsers && app.userId != userId) {
12092                    continue;
12093                }
12094                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12095                    // Generate process state info for running application
12096                    ActivityManager.RunningAppProcessInfo currApp =
12097                        new ActivityManager.RunningAppProcessInfo(app.processName,
12098                                app.pid, app.getPackageList());
12099                    fillInProcMemInfo(app, currApp);
12100                    if (app.adjSource instanceof ProcessRecord) {
12101                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12102                        currApp.importanceReasonImportance =
12103                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12104                                        app.adjSourceProcState);
12105                    } else if (app.adjSource instanceof ActivityRecord) {
12106                        ActivityRecord r = (ActivityRecord)app.adjSource;
12107                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12108                    }
12109                    if (app.adjTarget instanceof ComponentName) {
12110                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12111                    }
12112                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12113                    //        + " lru=" + currApp.lru);
12114                    if (runList == null) {
12115                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12116                    }
12117                    runList.add(currApp);
12118                }
12119            }
12120        }
12121        return runList;
12122    }
12123
12124    public List<ApplicationInfo> getRunningExternalApplications() {
12125        enforceNotIsolatedCaller("getRunningExternalApplications");
12126        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12127        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12128        if (runningApps != null && runningApps.size() > 0) {
12129            Set<String> extList = new HashSet<String>();
12130            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12131                if (app.pkgList != null) {
12132                    for (String pkg : app.pkgList) {
12133                        extList.add(pkg);
12134                    }
12135                }
12136            }
12137            IPackageManager pm = AppGlobals.getPackageManager();
12138            for (String pkg : extList) {
12139                try {
12140                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12141                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12142                        retList.add(info);
12143                    }
12144                } catch (RemoteException e) {
12145                }
12146            }
12147        }
12148        return retList;
12149    }
12150
12151    @Override
12152    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12153        enforceNotIsolatedCaller("getMyMemoryState");
12154        synchronized (this) {
12155            ProcessRecord proc;
12156            synchronized (mPidsSelfLocked) {
12157                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12158            }
12159            fillInProcMemInfo(proc, outInfo);
12160        }
12161    }
12162
12163    @Override
12164    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12165        if (checkCallingPermission(android.Manifest.permission.DUMP)
12166                != PackageManager.PERMISSION_GRANTED) {
12167            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12168                    + Binder.getCallingPid()
12169                    + ", uid=" + Binder.getCallingUid()
12170                    + " without permission "
12171                    + android.Manifest.permission.DUMP);
12172            return;
12173        }
12174
12175        boolean dumpAll = false;
12176        boolean dumpClient = false;
12177        String dumpPackage = null;
12178
12179        int opti = 0;
12180        while (opti < args.length) {
12181            String opt = args[opti];
12182            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12183                break;
12184            }
12185            opti++;
12186            if ("-a".equals(opt)) {
12187                dumpAll = true;
12188            } else if ("-c".equals(opt)) {
12189                dumpClient = true;
12190            } else if ("-h".equals(opt)) {
12191                pw.println("Activity manager dump options:");
12192                pw.println("  [-a] [-c] [-h] [cmd] ...");
12193                pw.println("  cmd may be one of:");
12194                pw.println("    a[ctivities]: activity stack state");
12195                pw.println("    r[recents]: recent activities state");
12196                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12197                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12198                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12199                pw.println("    o[om]: out of memory management");
12200                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12201                pw.println("    provider [COMP_SPEC]: provider client-side state");
12202                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12203                pw.println("    service [COMP_SPEC]: service client-side state");
12204                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12205                pw.println("    all: dump all activities");
12206                pw.println("    top: dump the top activity");
12207                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12208                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12209                pw.println("    a partial substring in a component name, a");
12210                pw.println("    hex object identifier.");
12211                pw.println("  -a: include all available server state.");
12212                pw.println("  -c: include client state.");
12213                return;
12214            } else {
12215                pw.println("Unknown argument: " + opt + "; use -h for help");
12216            }
12217        }
12218
12219        long origId = Binder.clearCallingIdentity();
12220        boolean more = false;
12221        // Is the caller requesting to dump a particular piece of data?
12222        if (opti < args.length) {
12223            String cmd = args[opti];
12224            opti++;
12225            if ("activities".equals(cmd) || "a".equals(cmd)) {
12226                synchronized (this) {
12227                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12228                }
12229            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12230                synchronized (this) {
12231                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12232                }
12233            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12234                String[] newArgs;
12235                String name;
12236                if (opti >= args.length) {
12237                    name = null;
12238                    newArgs = EMPTY_STRING_ARRAY;
12239                } else {
12240                    name = args[opti];
12241                    opti++;
12242                    newArgs = new String[args.length - opti];
12243                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12244                            args.length - opti);
12245                }
12246                synchronized (this) {
12247                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12248                }
12249            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12250                String[] newArgs;
12251                String name;
12252                if (opti >= args.length) {
12253                    name = null;
12254                    newArgs = EMPTY_STRING_ARRAY;
12255                } else {
12256                    name = args[opti];
12257                    opti++;
12258                    newArgs = new String[args.length - opti];
12259                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12260                            args.length - opti);
12261                }
12262                synchronized (this) {
12263                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12264                }
12265            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12266                String[] newArgs;
12267                String name;
12268                if (opti >= args.length) {
12269                    name = null;
12270                    newArgs = EMPTY_STRING_ARRAY;
12271                } else {
12272                    name = args[opti];
12273                    opti++;
12274                    newArgs = new String[args.length - opti];
12275                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12276                            args.length - opti);
12277                }
12278                synchronized (this) {
12279                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12280                }
12281            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12282                synchronized (this) {
12283                    dumpOomLocked(fd, pw, args, opti, true);
12284                }
12285            } else if ("provider".equals(cmd)) {
12286                String[] newArgs;
12287                String name;
12288                if (opti >= args.length) {
12289                    name = null;
12290                    newArgs = EMPTY_STRING_ARRAY;
12291                } else {
12292                    name = args[opti];
12293                    opti++;
12294                    newArgs = new String[args.length - opti];
12295                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12296                }
12297                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12298                    pw.println("No providers match: " + name);
12299                    pw.println("Use -h for help.");
12300                }
12301            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12302                synchronized (this) {
12303                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12304                }
12305            } else if ("service".equals(cmd)) {
12306                String[] newArgs;
12307                String name;
12308                if (opti >= args.length) {
12309                    name = null;
12310                    newArgs = EMPTY_STRING_ARRAY;
12311                } else {
12312                    name = args[opti];
12313                    opti++;
12314                    newArgs = new String[args.length - opti];
12315                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12316                            args.length - opti);
12317                }
12318                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12319                    pw.println("No services match: " + name);
12320                    pw.println("Use -h for help.");
12321                }
12322            } else if ("package".equals(cmd)) {
12323                String[] newArgs;
12324                if (opti >= args.length) {
12325                    pw.println("package: no package name specified");
12326                    pw.println("Use -h for help.");
12327                } else {
12328                    dumpPackage = args[opti];
12329                    opti++;
12330                    newArgs = new String[args.length - opti];
12331                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12332                            args.length - opti);
12333                    args = newArgs;
12334                    opti = 0;
12335                    more = true;
12336                }
12337            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12338                synchronized (this) {
12339                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12340                }
12341            } else {
12342                // Dumping a single activity?
12343                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12344                    pw.println("Bad activity command, or no activities match: " + cmd);
12345                    pw.println("Use -h for help.");
12346                }
12347            }
12348            if (!more) {
12349                Binder.restoreCallingIdentity(origId);
12350                return;
12351            }
12352        }
12353
12354        // No piece of data specified, dump everything.
12355        synchronized (this) {
12356            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12357            pw.println();
12358            if (dumpAll) {
12359                pw.println("-------------------------------------------------------------------------------");
12360            }
12361            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12362            pw.println();
12363            if (dumpAll) {
12364                pw.println("-------------------------------------------------------------------------------");
12365            }
12366            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12367            pw.println();
12368            if (dumpAll) {
12369                pw.println("-------------------------------------------------------------------------------");
12370            }
12371            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12372            pw.println();
12373            if (dumpAll) {
12374                pw.println("-------------------------------------------------------------------------------");
12375            }
12376            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12377            pw.println();
12378            if (dumpAll) {
12379                pw.println("-------------------------------------------------------------------------------");
12380            }
12381            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12382            pw.println();
12383            if (dumpAll) {
12384                pw.println("-------------------------------------------------------------------------------");
12385            }
12386            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12387        }
12388        Binder.restoreCallingIdentity(origId);
12389    }
12390
12391    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12392            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12393        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12394
12395        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12396                dumpPackage);
12397        boolean needSep = printedAnything;
12398
12399        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12400                dumpPackage, needSep, "  mFocusedActivity: ");
12401        if (printed) {
12402            printedAnything = true;
12403            needSep = false;
12404        }
12405
12406        if (dumpPackage == null) {
12407            if (needSep) {
12408                pw.println();
12409            }
12410            needSep = true;
12411            printedAnything = true;
12412            mStackSupervisor.dump(pw, "  ");
12413        }
12414
12415        if (!printedAnything) {
12416            pw.println("  (nothing)");
12417        }
12418    }
12419
12420    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12421            int opti, boolean dumpAll, String dumpPackage) {
12422        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12423
12424        boolean printedAnything = false;
12425
12426        if (mRecentTasks.size() > 0) {
12427            boolean printedHeader = false;
12428
12429            final int N = mRecentTasks.size();
12430            for (int i=0; i<N; i++) {
12431                TaskRecord tr = mRecentTasks.get(i);
12432                if (dumpPackage != null) {
12433                    if (tr.realActivity == null ||
12434                            !dumpPackage.equals(tr.realActivity)) {
12435                        continue;
12436                    }
12437                }
12438                if (!printedHeader) {
12439                    pw.println("  Recent tasks:");
12440                    printedHeader = true;
12441                    printedAnything = true;
12442                }
12443                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12444                        pw.println(tr);
12445                if (dumpAll) {
12446                    mRecentTasks.get(i).dump(pw, "    ");
12447                }
12448            }
12449        }
12450
12451        if (!printedAnything) {
12452            pw.println("  (nothing)");
12453        }
12454    }
12455
12456    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12457            int opti, boolean dumpAll, String dumpPackage) {
12458        boolean needSep = false;
12459        boolean printedAnything = false;
12460        int numPers = 0;
12461
12462        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12463
12464        if (dumpAll) {
12465            final int NP = mProcessNames.getMap().size();
12466            for (int ip=0; ip<NP; ip++) {
12467                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12468                final int NA = procs.size();
12469                for (int ia=0; ia<NA; ia++) {
12470                    ProcessRecord r = procs.valueAt(ia);
12471                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12472                        continue;
12473                    }
12474                    if (!needSep) {
12475                        pw.println("  All known processes:");
12476                        needSep = true;
12477                        printedAnything = true;
12478                    }
12479                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12480                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12481                        pw.print(" "); pw.println(r);
12482                    r.dump(pw, "    ");
12483                    if (r.persistent) {
12484                        numPers++;
12485                    }
12486                }
12487            }
12488        }
12489
12490        if (mIsolatedProcesses.size() > 0) {
12491            boolean printed = false;
12492            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12493                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12494                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12495                    continue;
12496                }
12497                if (!printed) {
12498                    if (needSep) {
12499                        pw.println();
12500                    }
12501                    pw.println("  Isolated process list (sorted by uid):");
12502                    printedAnything = true;
12503                    printed = true;
12504                    needSep = true;
12505                }
12506                pw.println(String.format("%sIsolated #%2d: %s",
12507                        "    ", i, r.toString()));
12508            }
12509        }
12510
12511        if (mLruProcesses.size() > 0) {
12512            if (needSep) {
12513                pw.println();
12514            }
12515            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12516                    pw.print(" total, non-act at ");
12517                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12518                    pw.print(", non-svc at ");
12519                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12520                    pw.println("):");
12521            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12522            needSep = true;
12523            printedAnything = true;
12524        }
12525
12526        if (dumpAll || dumpPackage != null) {
12527            synchronized (mPidsSelfLocked) {
12528                boolean printed = false;
12529                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12530                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12531                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12532                        continue;
12533                    }
12534                    if (!printed) {
12535                        if (needSep) pw.println();
12536                        needSep = true;
12537                        pw.println("  PID mappings:");
12538                        printed = true;
12539                        printedAnything = true;
12540                    }
12541                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12542                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12543                }
12544            }
12545        }
12546
12547        if (mForegroundProcesses.size() > 0) {
12548            synchronized (mPidsSelfLocked) {
12549                boolean printed = false;
12550                for (int i=0; i<mForegroundProcesses.size(); i++) {
12551                    ProcessRecord r = mPidsSelfLocked.get(
12552                            mForegroundProcesses.valueAt(i).pid);
12553                    if (dumpPackage != null && (r == null
12554                            || !r.pkgList.containsKey(dumpPackage))) {
12555                        continue;
12556                    }
12557                    if (!printed) {
12558                        if (needSep) pw.println();
12559                        needSep = true;
12560                        pw.println("  Foreground Processes:");
12561                        printed = true;
12562                        printedAnything = true;
12563                    }
12564                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12565                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12566                }
12567            }
12568        }
12569
12570        if (mPersistentStartingProcesses.size() > 0) {
12571            if (needSep) pw.println();
12572            needSep = true;
12573            printedAnything = true;
12574            pw.println("  Persisent processes that are starting:");
12575            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12576                    "Starting Norm", "Restarting PERS", dumpPackage);
12577        }
12578
12579        if (mRemovedProcesses.size() > 0) {
12580            if (needSep) pw.println();
12581            needSep = true;
12582            printedAnything = true;
12583            pw.println("  Processes that are being removed:");
12584            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12585                    "Removed Norm", "Removed PERS", dumpPackage);
12586        }
12587
12588        if (mProcessesOnHold.size() > 0) {
12589            if (needSep) pw.println();
12590            needSep = true;
12591            printedAnything = true;
12592            pw.println("  Processes that are on old until the system is ready:");
12593            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12594                    "OnHold Norm", "OnHold PERS", dumpPackage);
12595        }
12596
12597        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12598
12599        if (mProcessCrashTimes.getMap().size() > 0) {
12600            boolean printed = false;
12601            long now = SystemClock.uptimeMillis();
12602            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12603            final int NP = pmap.size();
12604            for (int ip=0; ip<NP; ip++) {
12605                String pname = pmap.keyAt(ip);
12606                SparseArray<Long> uids = pmap.valueAt(ip);
12607                final int N = uids.size();
12608                for (int i=0; i<N; i++) {
12609                    int puid = uids.keyAt(i);
12610                    ProcessRecord r = mProcessNames.get(pname, puid);
12611                    if (dumpPackage != null && (r == null
12612                            || !r.pkgList.containsKey(dumpPackage))) {
12613                        continue;
12614                    }
12615                    if (!printed) {
12616                        if (needSep) pw.println();
12617                        needSep = true;
12618                        pw.println("  Time since processes crashed:");
12619                        printed = true;
12620                        printedAnything = true;
12621                    }
12622                    pw.print("    Process "); pw.print(pname);
12623                            pw.print(" uid "); pw.print(puid);
12624                            pw.print(": last crashed ");
12625                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12626                            pw.println(" ago");
12627                }
12628            }
12629        }
12630
12631        if (mBadProcesses.getMap().size() > 0) {
12632            boolean printed = false;
12633            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12634            final int NP = pmap.size();
12635            for (int ip=0; ip<NP; ip++) {
12636                String pname = pmap.keyAt(ip);
12637                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12638                final int N = uids.size();
12639                for (int i=0; i<N; i++) {
12640                    int puid = uids.keyAt(i);
12641                    ProcessRecord r = mProcessNames.get(pname, puid);
12642                    if (dumpPackage != null && (r == null
12643                            || !r.pkgList.containsKey(dumpPackage))) {
12644                        continue;
12645                    }
12646                    if (!printed) {
12647                        if (needSep) pw.println();
12648                        needSep = true;
12649                        pw.println("  Bad processes:");
12650                        printedAnything = true;
12651                    }
12652                    BadProcessInfo info = uids.valueAt(i);
12653                    pw.print("    Bad process "); pw.print(pname);
12654                            pw.print(" uid "); pw.print(puid);
12655                            pw.print(": crashed at time "); pw.println(info.time);
12656                    if (info.shortMsg != null) {
12657                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12658                    }
12659                    if (info.longMsg != null) {
12660                        pw.print("      Long msg: "); pw.println(info.longMsg);
12661                    }
12662                    if (info.stack != null) {
12663                        pw.println("      Stack:");
12664                        int lastPos = 0;
12665                        for (int pos=0; pos<info.stack.length(); pos++) {
12666                            if (info.stack.charAt(pos) == '\n') {
12667                                pw.print("        ");
12668                                pw.write(info.stack, lastPos, pos-lastPos);
12669                                pw.println();
12670                                lastPos = pos+1;
12671                            }
12672                        }
12673                        if (lastPos < info.stack.length()) {
12674                            pw.print("        ");
12675                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12676                            pw.println();
12677                        }
12678                    }
12679                }
12680            }
12681        }
12682
12683        if (dumpPackage == null) {
12684            pw.println();
12685            needSep = false;
12686            pw.println("  mStartedUsers:");
12687            for (int i=0; i<mStartedUsers.size(); i++) {
12688                UserStartedState uss = mStartedUsers.valueAt(i);
12689                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12690                        pw.print(": "); uss.dump("", pw);
12691            }
12692            pw.print("  mStartedUserArray: [");
12693            for (int i=0; i<mStartedUserArray.length; i++) {
12694                if (i > 0) pw.print(", ");
12695                pw.print(mStartedUserArray[i]);
12696            }
12697            pw.println("]");
12698            pw.print("  mUserLru: [");
12699            for (int i=0; i<mUserLru.size(); i++) {
12700                if (i > 0) pw.print(", ");
12701                pw.print(mUserLru.get(i));
12702            }
12703            pw.println("]");
12704            if (dumpAll) {
12705                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12706            }
12707            synchronized (mUserProfileGroupIdsSelfLocked) {
12708                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12709                    pw.println("  mUserProfileGroupIds:");
12710                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12711                        pw.print("    User #");
12712                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12713                        pw.print(" -> profile #");
12714                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12715                    }
12716                }
12717            }
12718        }
12719        if (mHomeProcess != null && (dumpPackage == null
12720                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12721            if (needSep) {
12722                pw.println();
12723                needSep = false;
12724            }
12725            pw.println("  mHomeProcess: " + mHomeProcess);
12726        }
12727        if (mPreviousProcess != null && (dumpPackage == null
12728                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12729            if (needSep) {
12730                pw.println();
12731                needSep = false;
12732            }
12733            pw.println("  mPreviousProcess: " + mPreviousProcess);
12734        }
12735        if (dumpAll) {
12736            StringBuilder sb = new StringBuilder(128);
12737            sb.append("  mPreviousProcessVisibleTime: ");
12738            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12739            pw.println(sb);
12740        }
12741        if (mHeavyWeightProcess != null && (dumpPackage == null
12742                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12743            if (needSep) {
12744                pw.println();
12745                needSep = false;
12746            }
12747            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12748        }
12749        if (dumpPackage == null) {
12750            pw.println("  mConfiguration: " + mConfiguration);
12751        }
12752        if (dumpAll) {
12753            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12754            if (mCompatModePackages.getPackages().size() > 0) {
12755                boolean printed = false;
12756                for (Map.Entry<String, Integer> entry
12757                        : mCompatModePackages.getPackages().entrySet()) {
12758                    String pkg = entry.getKey();
12759                    int mode = entry.getValue();
12760                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12761                        continue;
12762                    }
12763                    if (!printed) {
12764                        pw.println("  mScreenCompatPackages:");
12765                        printed = true;
12766                    }
12767                    pw.print("    "); pw.print(pkg); pw.print(": ");
12768                            pw.print(mode); pw.println();
12769                }
12770            }
12771        }
12772        if (dumpPackage == null) {
12773            if (mSleeping || mWentToSleep || mLockScreenShown) {
12774                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12775                        + " mLockScreenShown " + mLockScreenShown);
12776            }
12777            if (mShuttingDown || mRunningVoice) {
12778                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12779            }
12780        }
12781        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12782                || mOrigWaitForDebugger) {
12783            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12784                    || dumpPackage.equals(mOrigDebugApp)) {
12785                if (needSep) {
12786                    pw.println();
12787                    needSep = false;
12788                }
12789                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12790                        + " mDebugTransient=" + mDebugTransient
12791                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12792            }
12793        }
12794        if (mOpenGlTraceApp != null) {
12795            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12796                if (needSep) {
12797                    pw.println();
12798                    needSep = false;
12799                }
12800                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12801            }
12802        }
12803        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12804                || mProfileFd != null) {
12805            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12806                if (needSep) {
12807                    pw.println();
12808                    needSep = false;
12809                }
12810                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12811                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12812                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12813                        + mAutoStopProfiler);
12814                pw.println("  mProfileType=" + mProfileType);
12815            }
12816        }
12817        if (dumpPackage == null) {
12818            if (mAlwaysFinishActivities || mController != null) {
12819                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12820                        + " mController=" + mController);
12821            }
12822            if (dumpAll) {
12823                pw.println("  Total persistent processes: " + numPers);
12824                pw.println("  mProcessesReady=" + mProcessesReady
12825                        + " mSystemReady=" + mSystemReady);
12826                pw.println("  mBooting=" + mBooting
12827                        + " mBooted=" + mBooted
12828                        + " mFactoryTest=" + mFactoryTest);
12829                pw.print("  mLastPowerCheckRealtime=");
12830                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12831                        pw.println("");
12832                pw.print("  mLastPowerCheckUptime=");
12833                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12834                        pw.println("");
12835                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12836                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12837                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12838                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12839                        + " (" + mLruProcesses.size() + " total)"
12840                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12841                        + " mNumServiceProcs=" + mNumServiceProcs
12842                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12843                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12844                        + " mLastMemoryLevel" + mLastMemoryLevel
12845                        + " mLastNumProcesses" + mLastNumProcesses);
12846                long now = SystemClock.uptimeMillis();
12847                pw.print("  mLastIdleTime=");
12848                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12849                        pw.print(" mLowRamSinceLastIdle=");
12850                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12851                        pw.println();
12852            }
12853        }
12854
12855        if (!printedAnything) {
12856            pw.println("  (nothing)");
12857        }
12858    }
12859
12860    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12861            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12862        if (mProcessesToGc.size() > 0) {
12863            boolean printed = false;
12864            long now = SystemClock.uptimeMillis();
12865            for (int i=0; i<mProcessesToGc.size(); i++) {
12866                ProcessRecord proc = mProcessesToGc.get(i);
12867                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12868                    continue;
12869                }
12870                if (!printed) {
12871                    if (needSep) pw.println();
12872                    needSep = true;
12873                    pw.println("  Processes that are waiting to GC:");
12874                    printed = true;
12875                }
12876                pw.print("    Process "); pw.println(proc);
12877                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12878                        pw.print(", last gced=");
12879                        pw.print(now-proc.lastRequestedGc);
12880                        pw.print(" ms ago, last lowMem=");
12881                        pw.print(now-proc.lastLowMemory);
12882                        pw.println(" ms ago");
12883
12884            }
12885        }
12886        return needSep;
12887    }
12888
12889    void printOomLevel(PrintWriter pw, String name, int adj) {
12890        pw.print("    ");
12891        if (adj >= 0) {
12892            pw.print(' ');
12893            if (adj < 10) pw.print(' ');
12894        } else {
12895            if (adj > -10) pw.print(' ');
12896        }
12897        pw.print(adj);
12898        pw.print(": ");
12899        pw.print(name);
12900        pw.print(" (");
12901        pw.print(mProcessList.getMemLevel(adj)/1024);
12902        pw.println(" kB)");
12903    }
12904
12905    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12906            int opti, boolean dumpAll) {
12907        boolean needSep = false;
12908
12909        if (mLruProcesses.size() > 0) {
12910            if (needSep) pw.println();
12911            needSep = true;
12912            pw.println("  OOM levels:");
12913            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12914            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12915            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12916            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12917            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12918            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12919            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12920            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12921            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12922            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12923            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12924            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12925            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12926
12927            if (needSep) pw.println();
12928            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12929                    pw.print(" total, non-act at ");
12930                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12931                    pw.print(", non-svc at ");
12932                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12933                    pw.println("):");
12934            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12935            needSep = true;
12936        }
12937
12938        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12939
12940        pw.println();
12941        pw.println("  mHomeProcess: " + mHomeProcess);
12942        pw.println("  mPreviousProcess: " + mPreviousProcess);
12943        if (mHeavyWeightProcess != null) {
12944            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12945        }
12946
12947        return true;
12948    }
12949
12950    /**
12951     * There are three ways to call this:
12952     *  - no provider specified: dump all the providers
12953     *  - a flattened component name that matched an existing provider was specified as the
12954     *    first arg: dump that one provider
12955     *  - the first arg isn't the flattened component name of an existing provider:
12956     *    dump all providers whose component contains the first arg as a substring
12957     */
12958    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12959            int opti, boolean dumpAll) {
12960        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12961    }
12962
12963    static class ItemMatcher {
12964        ArrayList<ComponentName> components;
12965        ArrayList<String> strings;
12966        ArrayList<Integer> objects;
12967        boolean all;
12968
12969        ItemMatcher() {
12970            all = true;
12971        }
12972
12973        void build(String name) {
12974            ComponentName componentName = ComponentName.unflattenFromString(name);
12975            if (componentName != null) {
12976                if (components == null) {
12977                    components = new ArrayList<ComponentName>();
12978                }
12979                components.add(componentName);
12980                all = false;
12981            } else {
12982                int objectId = 0;
12983                // Not a '/' separated full component name; maybe an object ID?
12984                try {
12985                    objectId = Integer.parseInt(name, 16);
12986                    if (objects == null) {
12987                        objects = new ArrayList<Integer>();
12988                    }
12989                    objects.add(objectId);
12990                    all = false;
12991                } catch (RuntimeException e) {
12992                    // Not an integer; just do string match.
12993                    if (strings == null) {
12994                        strings = new ArrayList<String>();
12995                    }
12996                    strings.add(name);
12997                    all = false;
12998                }
12999            }
13000        }
13001
13002        int build(String[] args, int opti) {
13003            for (; opti<args.length; opti++) {
13004                String name = args[opti];
13005                if ("--".equals(name)) {
13006                    return opti+1;
13007                }
13008                build(name);
13009            }
13010            return opti;
13011        }
13012
13013        boolean match(Object object, ComponentName comp) {
13014            if (all) {
13015                return true;
13016            }
13017            if (components != null) {
13018                for (int i=0; i<components.size(); i++) {
13019                    if (components.get(i).equals(comp)) {
13020                        return true;
13021                    }
13022                }
13023            }
13024            if (objects != null) {
13025                for (int i=0; i<objects.size(); i++) {
13026                    if (System.identityHashCode(object) == objects.get(i)) {
13027                        return true;
13028                    }
13029                }
13030            }
13031            if (strings != null) {
13032                String flat = comp.flattenToString();
13033                for (int i=0; i<strings.size(); i++) {
13034                    if (flat.contains(strings.get(i))) {
13035                        return true;
13036                    }
13037                }
13038            }
13039            return false;
13040        }
13041    }
13042
13043    /**
13044     * There are three things that cmd can be:
13045     *  - a flattened component name that matches an existing activity
13046     *  - the cmd arg isn't the flattened component name of an existing activity:
13047     *    dump all activity whose component contains the cmd as a substring
13048     *  - A hex number of the ActivityRecord object instance.
13049     */
13050    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13051            int opti, boolean dumpAll) {
13052        ArrayList<ActivityRecord> activities;
13053
13054        synchronized (this) {
13055            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13056        }
13057
13058        if (activities.size() <= 0) {
13059            return false;
13060        }
13061
13062        String[] newArgs = new String[args.length - opti];
13063        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13064
13065        TaskRecord lastTask = null;
13066        boolean needSep = false;
13067        for (int i=activities.size()-1; i>=0; i--) {
13068            ActivityRecord r = activities.get(i);
13069            if (needSep) {
13070                pw.println();
13071            }
13072            needSep = true;
13073            synchronized (this) {
13074                if (lastTask != r.task) {
13075                    lastTask = r.task;
13076                    pw.print("TASK "); pw.print(lastTask.affinity);
13077                            pw.print(" id="); pw.println(lastTask.taskId);
13078                    if (dumpAll) {
13079                        lastTask.dump(pw, "  ");
13080                    }
13081                }
13082            }
13083            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13084        }
13085        return true;
13086    }
13087
13088    /**
13089     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13090     * there is a thread associated with the activity.
13091     */
13092    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13093            final ActivityRecord r, String[] args, boolean dumpAll) {
13094        String innerPrefix = prefix + "  ";
13095        synchronized (this) {
13096            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13097                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13098                    pw.print(" pid=");
13099                    if (r.app != null) pw.println(r.app.pid);
13100                    else pw.println("(not running)");
13101            if (dumpAll) {
13102                r.dump(pw, innerPrefix);
13103            }
13104        }
13105        if (r.app != null && r.app.thread != null) {
13106            // flush anything that is already in the PrintWriter since the thread is going
13107            // to write to the file descriptor directly
13108            pw.flush();
13109            try {
13110                TransferPipe tp = new TransferPipe();
13111                try {
13112                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13113                            r.appToken, innerPrefix, args);
13114                    tp.go(fd);
13115                } finally {
13116                    tp.kill();
13117                }
13118            } catch (IOException e) {
13119                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13120            } catch (RemoteException e) {
13121                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13122            }
13123        }
13124    }
13125
13126    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13127            int opti, boolean dumpAll, String dumpPackage) {
13128        boolean needSep = false;
13129        boolean onlyHistory = false;
13130        boolean printedAnything = false;
13131
13132        if ("history".equals(dumpPackage)) {
13133            if (opti < args.length && "-s".equals(args[opti])) {
13134                dumpAll = false;
13135            }
13136            onlyHistory = true;
13137            dumpPackage = null;
13138        }
13139
13140        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13141        if (!onlyHistory && dumpAll) {
13142            if (mRegisteredReceivers.size() > 0) {
13143                boolean printed = false;
13144                Iterator it = mRegisteredReceivers.values().iterator();
13145                while (it.hasNext()) {
13146                    ReceiverList r = (ReceiverList)it.next();
13147                    if (dumpPackage != null && (r.app == null ||
13148                            !dumpPackage.equals(r.app.info.packageName))) {
13149                        continue;
13150                    }
13151                    if (!printed) {
13152                        pw.println("  Registered Receivers:");
13153                        needSep = true;
13154                        printed = true;
13155                        printedAnything = true;
13156                    }
13157                    pw.print("  * "); pw.println(r);
13158                    r.dump(pw, "    ");
13159                }
13160            }
13161
13162            if (mReceiverResolver.dump(pw, needSep ?
13163                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13164                    "    ", dumpPackage, false)) {
13165                needSep = true;
13166                printedAnything = true;
13167            }
13168        }
13169
13170        for (BroadcastQueue q : mBroadcastQueues) {
13171            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13172            printedAnything |= needSep;
13173        }
13174
13175        needSep = true;
13176
13177        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13178            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13179                if (needSep) {
13180                    pw.println();
13181                }
13182                needSep = true;
13183                printedAnything = true;
13184                pw.print("  Sticky broadcasts for user ");
13185                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13186                StringBuilder sb = new StringBuilder(128);
13187                for (Map.Entry<String, ArrayList<Intent>> ent
13188                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13189                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13190                    if (dumpAll) {
13191                        pw.println(":");
13192                        ArrayList<Intent> intents = ent.getValue();
13193                        final int N = intents.size();
13194                        for (int i=0; i<N; i++) {
13195                            sb.setLength(0);
13196                            sb.append("    Intent: ");
13197                            intents.get(i).toShortString(sb, false, true, false, false);
13198                            pw.println(sb.toString());
13199                            Bundle bundle = intents.get(i).getExtras();
13200                            if (bundle != null) {
13201                                pw.print("      ");
13202                                pw.println(bundle.toString());
13203                            }
13204                        }
13205                    } else {
13206                        pw.println("");
13207                    }
13208                }
13209            }
13210        }
13211
13212        if (!onlyHistory && dumpAll) {
13213            pw.println();
13214            for (BroadcastQueue queue : mBroadcastQueues) {
13215                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13216                        + queue.mBroadcastsScheduled);
13217            }
13218            pw.println("  mHandler:");
13219            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13220            needSep = true;
13221            printedAnything = true;
13222        }
13223
13224        if (!printedAnything) {
13225            pw.println("  (nothing)");
13226        }
13227    }
13228
13229    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13230            int opti, boolean dumpAll, String dumpPackage) {
13231        boolean needSep;
13232        boolean printedAnything = false;
13233
13234        ItemMatcher matcher = new ItemMatcher();
13235        matcher.build(args, opti);
13236
13237        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13238
13239        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13240        printedAnything |= needSep;
13241
13242        if (mLaunchingProviders.size() > 0) {
13243            boolean printed = false;
13244            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13245                ContentProviderRecord r = mLaunchingProviders.get(i);
13246                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13247                    continue;
13248                }
13249                if (!printed) {
13250                    if (needSep) pw.println();
13251                    needSep = true;
13252                    pw.println("  Launching content providers:");
13253                    printed = true;
13254                    printedAnything = true;
13255                }
13256                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13257                        pw.println(r);
13258            }
13259        }
13260
13261        if (mGrantedUriPermissions.size() > 0) {
13262            boolean printed = false;
13263            int dumpUid = -2;
13264            if (dumpPackage != null) {
13265                try {
13266                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13267                } catch (NameNotFoundException e) {
13268                    dumpUid = -1;
13269                }
13270            }
13271            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13272                int uid = mGrantedUriPermissions.keyAt(i);
13273                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13274                    continue;
13275                }
13276                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13277                if (!printed) {
13278                    if (needSep) pw.println();
13279                    needSep = true;
13280                    pw.println("  Granted Uri Permissions:");
13281                    printed = true;
13282                    printedAnything = true;
13283                }
13284                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13285                for (UriPermission perm : perms.values()) {
13286                    pw.print("    "); pw.println(perm);
13287                    if (dumpAll) {
13288                        perm.dump(pw, "      ");
13289                    }
13290                }
13291            }
13292        }
13293
13294        if (!printedAnything) {
13295            pw.println("  (nothing)");
13296        }
13297    }
13298
13299    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13300            int opti, boolean dumpAll, String dumpPackage) {
13301        boolean printed = false;
13302
13303        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13304
13305        if (mIntentSenderRecords.size() > 0) {
13306            Iterator<WeakReference<PendingIntentRecord>> it
13307                    = mIntentSenderRecords.values().iterator();
13308            while (it.hasNext()) {
13309                WeakReference<PendingIntentRecord> ref = it.next();
13310                PendingIntentRecord rec = ref != null ? ref.get(): null;
13311                if (dumpPackage != null && (rec == null
13312                        || !dumpPackage.equals(rec.key.packageName))) {
13313                    continue;
13314                }
13315                printed = true;
13316                if (rec != null) {
13317                    pw.print("  * "); pw.println(rec);
13318                    if (dumpAll) {
13319                        rec.dump(pw, "    ");
13320                    }
13321                } else {
13322                    pw.print("  * "); pw.println(ref);
13323                }
13324            }
13325        }
13326
13327        if (!printed) {
13328            pw.println("  (nothing)");
13329        }
13330    }
13331
13332    private static final int dumpProcessList(PrintWriter pw,
13333            ActivityManagerService service, List list,
13334            String prefix, String normalLabel, String persistentLabel,
13335            String dumpPackage) {
13336        int numPers = 0;
13337        final int N = list.size()-1;
13338        for (int i=N; i>=0; i--) {
13339            ProcessRecord r = (ProcessRecord)list.get(i);
13340            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13341                continue;
13342            }
13343            pw.println(String.format("%s%s #%2d: %s",
13344                    prefix, (r.persistent ? persistentLabel : normalLabel),
13345                    i, r.toString()));
13346            if (r.persistent) {
13347                numPers++;
13348            }
13349        }
13350        return numPers;
13351    }
13352
13353    private static final boolean dumpProcessOomList(PrintWriter pw,
13354            ActivityManagerService service, List<ProcessRecord> origList,
13355            String prefix, String normalLabel, String persistentLabel,
13356            boolean inclDetails, String dumpPackage) {
13357
13358        ArrayList<Pair<ProcessRecord, Integer>> list
13359                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13360        for (int i=0; i<origList.size(); i++) {
13361            ProcessRecord r = origList.get(i);
13362            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13363                continue;
13364            }
13365            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13366        }
13367
13368        if (list.size() <= 0) {
13369            return false;
13370        }
13371
13372        Comparator<Pair<ProcessRecord, Integer>> comparator
13373                = new Comparator<Pair<ProcessRecord, Integer>>() {
13374            @Override
13375            public int compare(Pair<ProcessRecord, Integer> object1,
13376                    Pair<ProcessRecord, Integer> object2) {
13377                if (object1.first.setAdj != object2.first.setAdj) {
13378                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13379                }
13380                if (object1.second.intValue() != object2.second.intValue()) {
13381                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13382                }
13383                return 0;
13384            }
13385        };
13386
13387        Collections.sort(list, comparator);
13388
13389        final long curRealtime = SystemClock.elapsedRealtime();
13390        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13391        final long curUptime = SystemClock.uptimeMillis();
13392        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13393
13394        for (int i=list.size()-1; i>=0; i--) {
13395            ProcessRecord r = list.get(i).first;
13396            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13397            char schedGroup;
13398            switch (r.setSchedGroup) {
13399                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13400                    schedGroup = 'B';
13401                    break;
13402                case Process.THREAD_GROUP_DEFAULT:
13403                    schedGroup = 'F';
13404                    break;
13405                default:
13406                    schedGroup = '?';
13407                    break;
13408            }
13409            char foreground;
13410            if (r.foregroundActivities) {
13411                foreground = 'A';
13412            } else if (r.foregroundServices) {
13413                foreground = 'S';
13414            } else {
13415                foreground = ' ';
13416            }
13417            String procState = ProcessList.makeProcStateString(r.curProcState);
13418            pw.print(prefix);
13419            pw.print(r.persistent ? persistentLabel : normalLabel);
13420            pw.print(" #");
13421            int num = (origList.size()-1)-list.get(i).second;
13422            if (num < 10) pw.print(' ');
13423            pw.print(num);
13424            pw.print(": ");
13425            pw.print(oomAdj);
13426            pw.print(' ');
13427            pw.print(schedGroup);
13428            pw.print('/');
13429            pw.print(foreground);
13430            pw.print('/');
13431            pw.print(procState);
13432            pw.print(" trm:");
13433            if (r.trimMemoryLevel < 10) pw.print(' ');
13434            pw.print(r.trimMemoryLevel);
13435            pw.print(' ');
13436            pw.print(r.toShortString());
13437            pw.print(" (");
13438            pw.print(r.adjType);
13439            pw.println(')');
13440            if (r.adjSource != null || r.adjTarget != null) {
13441                pw.print(prefix);
13442                pw.print("    ");
13443                if (r.adjTarget instanceof ComponentName) {
13444                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13445                } else if (r.adjTarget != null) {
13446                    pw.print(r.adjTarget.toString());
13447                } else {
13448                    pw.print("{null}");
13449                }
13450                pw.print("<=");
13451                if (r.adjSource instanceof ProcessRecord) {
13452                    pw.print("Proc{");
13453                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13454                    pw.println("}");
13455                } else if (r.adjSource != null) {
13456                    pw.println(r.adjSource.toString());
13457                } else {
13458                    pw.println("{null}");
13459                }
13460            }
13461            if (inclDetails) {
13462                pw.print(prefix);
13463                pw.print("    ");
13464                pw.print("oom: max="); pw.print(r.maxAdj);
13465                pw.print(" curRaw="); pw.print(r.curRawAdj);
13466                pw.print(" setRaw="); pw.print(r.setRawAdj);
13467                pw.print(" cur="); pw.print(r.curAdj);
13468                pw.print(" set="); pw.println(r.setAdj);
13469                pw.print(prefix);
13470                pw.print("    ");
13471                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13472                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13473                pw.print(" lastPss="); pw.print(r.lastPss);
13474                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13475                pw.print(prefix);
13476                pw.print("    ");
13477                pw.print("cached="); pw.print(r.cached);
13478                pw.print(" empty="); pw.print(r.empty);
13479                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13480
13481                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13482                    if (r.lastWakeTime != 0) {
13483                        long wtime;
13484                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13485                        synchronized (stats) {
13486                            wtime = stats.getProcessWakeTime(r.info.uid,
13487                                    r.pid, curRealtime);
13488                        }
13489                        long timeUsed = wtime - r.lastWakeTime;
13490                        pw.print(prefix);
13491                        pw.print("    ");
13492                        pw.print("keep awake over ");
13493                        TimeUtils.formatDuration(realtimeSince, pw);
13494                        pw.print(" used ");
13495                        TimeUtils.formatDuration(timeUsed, pw);
13496                        pw.print(" (");
13497                        pw.print((timeUsed*100)/realtimeSince);
13498                        pw.println("%)");
13499                    }
13500                    if (r.lastCpuTime != 0) {
13501                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13502                        pw.print(prefix);
13503                        pw.print("    ");
13504                        pw.print("run cpu over ");
13505                        TimeUtils.formatDuration(uptimeSince, pw);
13506                        pw.print(" used ");
13507                        TimeUtils.formatDuration(timeUsed, pw);
13508                        pw.print(" (");
13509                        pw.print((timeUsed*100)/uptimeSince);
13510                        pw.println("%)");
13511                    }
13512                }
13513            }
13514        }
13515        return true;
13516    }
13517
13518    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13519        ArrayList<ProcessRecord> procs;
13520        synchronized (this) {
13521            if (args != null && args.length > start
13522                    && args[start].charAt(0) != '-') {
13523                procs = new ArrayList<ProcessRecord>();
13524                int pid = -1;
13525                try {
13526                    pid = Integer.parseInt(args[start]);
13527                } catch (NumberFormatException e) {
13528                }
13529                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13530                    ProcessRecord proc = mLruProcesses.get(i);
13531                    if (proc.pid == pid) {
13532                        procs.add(proc);
13533                    } else if (proc.processName.equals(args[start])) {
13534                        procs.add(proc);
13535                    }
13536                }
13537                if (procs.size() <= 0) {
13538                    return null;
13539                }
13540            } else {
13541                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13542            }
13543        }
13544        return procs;
13545    }
13546
13547    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13548            PrintWriter pw, String[] args) {
13549        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13550        if (procs == null) {
13551            pw.println("No process found for: " + args[0]);
13552            return;
13553        }
13554
13555        long uptime = SystemClock.uptimeMillis();
13556        long realtime = SystemClock.elapsedRealtime();
13557        pw.println("Applications Graphics Acceleration Info:");
13558        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13559
13560        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13561            ProcessRecord r = procs.get(i);
13562            if (r.thread != null) {
13563                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13564                pw.flush();
13565                try {
13566                    TransferPipe tp = new TransferPipe();
13567                    try {
13568                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13569                        tp.go(fd);
13570                    } finally {
13571                        tp.kill();
13572                    }
13573                } catch (IOException e) {
13574                    pw.println("Failure while dumping the app: " + r);
13575                    pw.flush();
13576                } catch (RemoteException e) {
13577                    pw.println("Got a RemoteException while dumping the app " + r);
13578                    pw.flush();
13579                }
13580            }
13581        }
13582    }
13583
13584    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13585        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13586        if (procs == null) {
13587            pw.println("No process found for: " + args[0]);
13588            return;
13589        }
13590
13591        pw.println("Applications Database Info:");
13592
13593        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13594            ProcessRecord r = procs.get(i);
13595            if (r.thread != null) {
13596                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13597                pw.flush();
13598                try {
13599                    TransferPipe tp = new TransferPipe();
13600                    try {
13601                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13602                        tp.go(fd);
13603                    } finally {
13604                        tp.kill();
13605                    }
13606                } catch (IOException e) {
13607                    pw.println("Failure while dumping the app: " + r);
13608                    pw.flush();
13609                } catch (RemoteException e) {
13610                    pw.println("Got a RemoteException while dumping the app " + r);
13611                    pw.flush();
13612                }
13613            }
13614        }
13615    }
13616
13617    final static class MemItem {
13618        final boolean isProc;
13619        final String label;
13620        final String shortLabel;
13621        final long pss;
13622        final int id;
13623        final boolean hasActivities;
13624        ArrayList<MemItem> subitems;
13625
13626        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13627                boolean _hasActivities) {
13628            isProc = true;
13629            label = _label;
13630            shortLabel = _shortLabel;
13631            pss = _pss;
13632            id = _id;
13633            hasActivities = _hasActivities;
13634        }
13635
13636        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13637            isProc = false;
13638            label = _label;
13639            shortLabel = _shortLabel;
13640            pss = _pss;
13641            id = _id;
13642            hasActivities = false;
13643        }
13644    }
13645
13646    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13647            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13648        if (sort && !isCompact) {
13649            Collections.sort(items, new Comparator<MemItem>() {
13650                @Override
13651                public int compare(MemItem lhs, MemItem rhs) {
13652                    if (lhs.pss < rhs.pss) {
13653                        return 1;
13654                    } else if (lhs.pss > rhs.pss) {
13655                        return -1;
13656                    }
13657                    return 0;
13658                }
13659            });
13660        }
13661
13662        for (int i=0; i<items.size(); i++) {
13663            MemItem mi = items.get(i);
13664            if (!isCompact) {
13665                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13666            } else if (mi.isProc) {
13667                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13668                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13669                pw.println(mi.hasActivities ? ",a" : ",e");
13670            } else {
13671                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13672                pw.println(mi.pss);
13673            }
13674            if (mi.subitems != null) {
13675                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13676                        true, isCompact);
13677            }
13678        }
13679    }
13680
13681    // These are in KB.
13682    static final long[] DUMP_MEM_BUCKETS = new long[] {
13683        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13684        120*1024, 160*1024, 200*1024,
13685        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13686        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13687    };
13688
13689    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13690            boolean stackLike) {
13691        int start = label.lastIndexOf('.');
13692        if (start >= 0) start++;
13693        else start = 0;
13694        int end = label.length();
13695        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13696            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13697                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13698                out.append(bucket);
13699                out.append(stackLike ? "MB." : "MB ");
13700                out.append(label, start, end);
13701                return;
13702            }
13703        }
13704        out.append(memKB/1024);
13705        out.append(stackLike ? "MB." : "MB ");
13706        out.append(label, start, end);
13707    }
13708
13709    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13710            ProcessList.NATIVE_ADJ,
13711            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13712            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13713            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13714            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13715            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13716    };
13717    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13718            "Native",
13719            "System", "Persistent", "Foreground",
13720            "Visible", "Perceptible",
13721            "Heavy Weight", "Backup",
13722            "A Services", "Home",
13723            "Previous", "B Services", "Cached"
13724    };
13725    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13726            "native",
13727            "sys", "pers", "fore",
13728            "vis", "percept",
13729            "heavy", "backup",
13730            "servicea", "home",
13731            "prev", "serviceb", "cached"
13732    };
13733
13734    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13735            long realtime, boolean isCheckinRequest, boolean isCompact) {
13736        if (isCheckinRequest || isCompact) {
13737            // short checkin version
13738            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13739        } else {
13740            pw.println("Applications Memory Usage (kB):");
13741            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13742        }
13743    }
13744
13745    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13746            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13747        boolean dumpDetails = false;
13748        boolean dumpFullDetails = false;
13749        boolean dumpDalvik = false;
13750        boolean oomOnly = false;
13751        boolean isCompact = false;
13752        boolean localOnly = false;
13753
13754        int opti = 0;
13755        while (opti < args.length) {
13756            String opt = args[opti];
13757            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13758                break;
13759            }
13760            opti++;
13761            if ("-a".equals(opt)) {
13762                dumpDetails = true;
13763                dumpFullDetails = true;
13764                dumpDalvik = true;
13765            } else if ("-d".equals(opt)) {
13766                dumpDalvik = true;
13767            } else if ("-c".equals(opt)) {
13768                isCompact = true;
13769            } else if ("--oom".equals(opt)) {
13770                oomOnly = true;
13771            } else if ("--local".equals(opt)) {
13772                localOnly = true;
13773            } else if ("-h".equals(opt)) {
13774                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13775                pw.println("  -a: include all available information for each process.");
13776                pw.println("  -d: include dalvik details when dumping process details.");
13777                pw.println("  -c: dump in a compact machine-parseable representation.");
13778                pw.println("  --oom: only show processes organized by oom adj.");
13779                pw.println("  --local: only collect details locally, don't call process.");
13780                pw.println("If [process] is specified it can be the name or ");
13781                pw.println("pid of a specific process to dump.");
13782                return;
13783            } else {
13784                pw.println("Unknown argument: " + opt + "; use -h for help");
13785            }
13786        }
13787
13788        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13789        long uptime = SystemClock.uptimeMillis();
13790        long realtime = SystemClock.elapsedRealtime();
13791        final long[] tmpLong = new long[1];
13792
13793        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13794        if (procs == null) {
13795            // No Java processes.  Maybe they want to print a native process.
13796            if (args != null && args.length > opti
13797                    && args[opti].charAt(0) != '-') {
13798                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13799                        = new ArrayList<ProcessCpuTracker.Stats>();
13800                updateCpuStatsNow();
13801                int findPid = -1;
13802                try {
13803                    findPid = Integer.parseInt(args[opti]);
13804                } catch (NumberFormatException e) {
13805                }
13806                synchronized (mProcessCpuTracker) {
13807                    final int N = mProcessCpuTracker.countStats();
13808                    for (int i=0; i<N; i++) {
13809                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13810                        if (st.pid == findPid || (st.baseName != null
13811                                && st.baseName.equals(args[opti]))) {
13812                            nativeProcs.add(st);
13813                        }
13814                    }
13815                }
13816                if (nativeProcs.size() > 0) {
13817                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13818                            isCompact);
13819                    Debug.MemoryInfo mi = null;
13820                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13821                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13822                        final int pid = r.pid;
13823                        if (!isCheckinRequest && dumpDetails) {
13824                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13825                        }
13826                        if (mi == null) {
13827                            mi = new Debug.MemoryInfo();
13828                        }
13829                        if (dumpDetails || (!brief && !oomOnly)) {
13830                            Debug.getMemoryInfo(pid, mi);
13831                        } else {
13832                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13833                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13834                        }
13835                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13836                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13837                        if (isCheckinRequest) {
13838                            pw.println();
13839                        }
13840                    }
13841                    return;
13842                }
13843            }
13844            pw.println("No process found for: " + args[opti]);
13845            return;
13846        }
13847
13848        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13849            dumpDetails = true;
13850        }
13851
13852        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13853
13854        String[] innerArgs = new String[args.length-opti];
13855        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13856
13857        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13858        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13859        long nativePss=0, dalvikPss=0, otherPss=0;
13860        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13861
13862        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13863        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13864                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13865
13866        long totalPss = 0;
13867        long cachedPss = 0;
13868
13869        Debug.MemoryInfo mi = null;
13870        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13871            final ProcessRecord r = procs.get(i);
13872            final IApplicationThread thread;
13873            final int pid;
13874            final int oomAdj;
13875            final boolean hasActivities;
13876            synchronized (this) {
13877                thread = r.thread;
13878                pid = r.pid;
13879                oomAdj = r.getSetAdjWithServices();
13880                hasActivities = r.activities.size() > 0;
13881            }
13882            if (thread != null) {
13883                if (!isCheckinRequest && dumpDetails) {
13884                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13885                }
13886                if (mi == null) {
13887                    mi = new Debug.MemoryInfo();
13888                }
13889                if (dumpDetails || (!brief && !oomOnly)) {
13890                    Debug.getMemoryInfo(pid, mi);
13891                } else {
13892                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13893                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13894                }
13895                if (dumpDetails) {
13896                    if (localOnly) {
13897                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13898                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13899                        if (isCheckinRequest) {
13900                            pw.println();
13901                        }
13902                    } else {
13903                        try {
13904                            pw.flush();
13905                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13906                                    dumpDalvik, innerArgs);
13907                        } catch (RemoteException e) {
13908                            if (!isCheckinRequest) {
13909                                pw.println("Got RemoteException!");
13910                                pw.flush();
13911                            }
13912                        }
13913                    }
13914                }
13915
13916                final long myTotalPss = mi.getTotalPss();
13917                final long myTotalUss = mi.getTotalUss();
13918
13919                synchronized (this) {
13920                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13921                        // Record this for posterity if the process has been stable.
13922                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13923                    }
13924                }
13925
13926                if (!isCheckinRequest && mi != null) {
13927                    totalPss += myTotalPss;
13928                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13929                            (hasActivities ? " / activities)" : ")"),
13930                            r.processName, myTotalPss, pid, hasActivities);
13931                    procMems.add(pssItem);
13932                    procMemsMap.put(pid, pssItem);
13933
13934                    nativePss += mi.nativePss;
13935                    dalvikPss += mi.dalvikPss;
13936                    otherPss += mi.otherPss;
13937                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13938                        long mem = mi.getOtherPss(j);
13939                        miscPss[j] += mem;
13940                        otherPss -= mem;
13941                    }
13942
13943                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13944                        cachedPss += myTotalPss;
13945                    }
13946
13947                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13948                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13949                                || oomIndex == (oomPss.length-1)) {
13950                            oomPss[oomIndex] += myTotalPss;
13951                            if (oomProcs[oomIndex] == null) {
13952                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13953                            }
13954                            oomProcs[oomIndex].add(pssItem);
13955                            break;
13956                        }
13957                    }
13958                }
13959            }
13960        }
13961
13962        long nativeProcTotalPss = 0;
13963
13964        if (!isCheckinRequest && procs.size() > 1) {
13965            // If we are showing aggregations, also look for native processes to
13966            // include so that our aggregations are more accurate.
13967            updateCpuStatsNow();
13968            synchronized (mProcessCpuTracker) {
13969                final int N = mProcessCpuTracker.countStats();
13970                for (int i=0; i<N; i++) {
13971                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13972                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13973                        if (mi == null) {
13974                            mi = new Debug.MemoryInfo();
13975                        }
13976                        if (!brief && !oomOnly) {
13977                            Debug.getMemoryInfo(st.pid, mi);
13978                        } else {
13979                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13980                            mi.nativePrivateDirty = (int)tmpLong[0];
13981                        }
13982
13983                        final long myTotalPss = mi.getTotalPss();
13984                        totalPss += myTotalPss;
13985                        nativeProcTotalPss += myTotalPss;
13986
13987                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13988                                st.name, myTotalPss, st.pid, false);
13989                        procMems.add(pssItem);
13990
13991                        nativePss += mi.nativePss;
13992                        dalvikPss += mi.dalvikPss;
13993                        otherPss += mi.otherPss;
13994                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13995                            long mem = mi.getOtherPss(j);
13996                            miscPss[j] += mem;
13997                            otherPss -= mem;
13998                        }
13999                        oomPss[0] += myTotalPss;
14000                        if (oomProcs[0] == null) {
14001                            oomProcs[0] = new ArrayList<MemItem>();
14002                        }
14003                        oomProcs[0].add(pssItem);
14004                    }
14005                }
14006            }
14007
14008            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14009
14010            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14011            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14012            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14013            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14014                String label = Debug.MemoryInfo.getOtherLabel(j);
14015                catMems.add(new MemItem(label, label, miscPss[j], j));
14016            }
14017
14018            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14019            for (int j=0; j<oomPss.length; j++) {
14020                if (oomPss[j] != 0) {
14021                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14022                            : DUMP_MEM_OOM_LABEL[j];
14023                    MemItem item = new MemItem(label, label, oomPss[j],
14024                            DUMP_MEM_OOM_ADJ[j]);
14025                    item.subitems = oomProcs[j];
14026                    oomMems.add(item);
14027                }
14028            }
14029
14030            if (!brief && !oomOnly && !isCompact) {
14031                pw.println();
14032                pw.println("Total PSS by process:");
14033                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14034                pw.println();
14035            }
14036            if (!isCompact) {
14037                pw.println("Total PSS by OOM adjustment:");
14038            }
14039            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14040            if (!brief && !oomOnly) {
14041                PrintWriter out = categoryPw != null ? categoryPw : pw;
14042                if (!isCompact) {
14043                    out.println();
14044                    out.println("Total PSS by category:");
14045                }
14046                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14047            }
14048            if (!isCompact) {
14049                pw.println();
14050            }
14051            MemInfoReader memInfo = new MemInfoReader();
14052            memInfo.readMemInfo();
14053            if (nativeProcTotalPss > 0) {
14054                synchronized (this) {
14055                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14056                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14057                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14058                            nativeProcTotalPss);
14059                }
14060            }
14061            if (!brief) {
14062                if (!isCompact) {
14063                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14064                    pw.print(" kB (status ");
14065                    switch (mLastMemoryLevel) {
14066                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14067                            pw.println("normal)");
14068                            break;
14069                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14070                            pw.println("moderate)");
14071                            break;
14072                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14073                            pw.println("low)");
14074                            break;
14075                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14076                            pw.println("critical)");
14077                            break;
14078                        default:
14079                            pw.print(mLastMemoryLevel);
14080                            pw.println(")");
14081                            break;
14082                    }
14083                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14084                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14085                            pw.print(cachedPss); pw.print(" cached pss + ");
14086                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14087                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14088                } else {
14089                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14090                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14091                            + memInfo.getFreeSizeKb()); pw.print(",");
14092                    pw.println(totalPss - cachedPss);
14093                }
14094            }
14095            if (!isCompact) {
14096                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14097                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14098                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14099                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14100                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14101                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14102                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14103                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14104                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14105                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14106                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14107            }
14108            if (!brief) {
14109                if (memInfo.getZramTotalSizeKb() != 0) {
14110                    if (!isCompact) {
14111                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14112                                pw.print(" kB physical used for ");
14113                                pw.print(memInfo.getSwapTotalSizeKb()
14114                                        - memInfo.getSwapFreeSizeKb());
14115                                pw.print(" kB in swap (");
14116                                pw.print(memInfo.getSwapTotalSizeKb());
14117                                pw.println(" kB total swap)");
14118                    } else {
14119                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14120                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14121                                pw.println(memInfo.getSwapFreeSizeKb());
14122                    }
14123                }
14124                final int[] SINGLE_LONG_FORMAT = new int[] {
14125                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14126                };
14127                long[] longOut = new long[1];
14128                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14129                        SINGLE_LONG_FORMAT, null, longOut, null);
14130                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14131                longOut[0] = 0;
14132                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14133                        SINGLE_LONG_FORMAT, null, longOut, null);
14134                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14135                longOut[0] = 0;
14136                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14137                        SINGLE_LONG_FORMAT, null, longOut, null);
14138                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14139                longOut[0] = 0;
14140                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14141                        SINGLE_LONG_FORMAT, null, longOut, null);
14142                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14143                if (!isCompact) {
14144                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14145                        pw.print("      KSM: "); pw.print(sharing);
14146                                pw.print(" kB saved from shared ");
14147                                pw.print(shared); pw.println(" kB");
14148                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14149                                pw.print(voltile); pw.println(" kB volatile");
14150                    }
14151                    pw.print("   Tuning: ");
14152                    pw.print(ActivityManager.staticGetMemoryClass());
14153                    pw.print(" (large ");
14154                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14155                    pw.print("), oom ");
14156                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14157                    pw.print(" kB");
14158                    pw.print(", restore limit ");
14159                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14160                    pw.print(" kB");
14161                    if (ActivityManager.isLowRamDeviceStatic()) {
14162                        pw.print(" (low-ram)");
14163                    }
14164                    if (ActivityManager.isHighEndGfx()) {
14165                        pw.print(" (high-end-gfx)");
14166                    }
14167                    pw.println();
14168                } else {
14169                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14170                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14171                    pw.println(voltile);
14172                    pw.print("tuning,");
14173                    pw.print(ActivityManager.staticGetMemoryClass());
14174                    pw.print(',');
14175                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14176                    pw.print(',');
14177                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14178                    if (ActivityManager.isLowRamDeviceStatic()) {
14179                        pw.print(",low-ram");
14180                    }
14181                    if (ActivityManager.isHighEndGfx()) {
14182                        pw.print(",high-end-gfx");
14183                    }
14184                    pw.println();
14185                }
14186            }
14187        }
14188    }
14189
14190    /**
14191     * Searches array of arguments for the specified string
14192     * @param args array of argument strings
14193     * @param value value to search for
14194     * @return true if the value is contained in the array
14195     */
14196    private static boolean scanArgs(String[] args, String value) {
14197        if (args != null) {
14198            for (String arg : args) {
14199                if (value.equals(arg)) {
14200                    return true;
14201                }
14202            }
14203        }
14204        return false;
14205    }
14206
14207    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14208            ContentProviderRecord cpr, boolean always) {
14209        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14210
14211        if (!inLaunching || always) {
14212            synchronized (cpr) {
14213                cpr.launchingApp = null;
14214                cpr.notifyAll();
14215            }
14216            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14217            String names[] = cpr.info.authority.split(";");
14218            for (int j = 0; j < names.length; j++) {
14219                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14220            }
14221        }
14222
14223        for (int i=0; i<cpr.connections.size(); i++) {
14224            ContentProviderConnection conn = cpr.connections.get(i);
14225            if (conn.waiting) {
14226                // If this connection is waiting for the provider, then we don't
14227                // need to mess with its process unless we are always removing
14228                // or for some reason the provider is not currently launching.
14229                if (inLaunching && !always) {
14230                    continue;
14231                }
14232            }
14233            ProcessRecord capp = conn.client;
14234            conn.dead = true;
14235            if (conn.stableCount > 0) {
14236                if (!capp.persistent && capp.thread != null
14237                        && capp.pid != 0
14238                        && capp.pid != MY_PID) {
14239                    capp.kill("depends on provider "
14240                            + cpr.name.flattenToShortString()
14241                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14242                }
14243            } else if (capp.thread != null && conn.provider.provider != null) {
14244                try {
14245                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14246                } catch (RemoteException e) {
14247                }
14248                // In the protocol here, we don't expect the client to correctly
14249                // clean up this connection, we'll just remove it.
14250                cpr.connections.remove(i);
14251                conn.client.conProviders.remove(conn);
14252            }
14253        }
14254
14255        if (inLaunching && always) {
14256            mLaunchingProviders.remove(cpr);
14257        }
14258        return inLaunching;
14259    }
14260
14261    /**
14262     * Main code for cleaning up a process when it has gone away.  This is
14263     * called both as a result of the process dying, or directly when stopping
14264     * a process when running in single process mode.
14265     */
14266    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14267            boolean restarting, boolean allowRestart, int index) {
14268        if (index >= 0) {
14269            removeLruProcessLocked(app);
14270            ProcessList.remove(app.pid);
14271        }
14272
14273        mProcessesToGc.remove(app);
14274        mPendingPssProcesses.remove(app);
14275
14276        // Dismiss any open dialogs.
14277        if (app.crashDialog != null && !app.forceCrashReport) {
14278            app.crashDialog.dismiss();
14279            app.crashDialog = null;
14280        }
14281        if (app.anrDialog != null) {
14282            app.anrDialog.dismiss();
14283            app.anrDialog = null;
14284        }
14285        if (app.waitDialog != null) {
14286            app.waitDialog.dismiss();
14287            app.waitDialog = null;
14288        }
14289
14290        app.crashing = false;
14291        app.notResponding = false;
14292
14293        app.resetPackageList(mProcessStats);
14294        app.unlinkDeathRecipient();
14295        app.makeInactive(mProcessStats);
14296        app.waitingToKill = null;
14297        app.forcingToForeground = null;
14298        updateProcessForegroundLocked(app, false, false);
14299        app.foregroundActivities = false;
14300        app.hasShownUi = false;
14301        app.treatLikeActivity = false;
14302        app.hasAboveClient = false;
14303        app.hasClientActivities = false;
14304
14305        mServices.killServicesLocked(app, allowRestart);
14306
14307        boolean restart = false;
14308
14309        // Remove published content providers.
14310        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14311            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14312            final boolean always = app.bad || !allowRestart;
14313            if (removeDyingProviderLocked(app, cpr, always) || always) {
14314                // We left the provider in the launching list, need to
14315                // restart it.
14316                restart = true;
14317            }
14318
14319            cpr.provider = null;
14320            cpr.proc = null;
14321        }
14322        app.pubProviders.clear();
14323
14324        // Take care of any launching providers waiting for this process.
14325        if (checkAppInLaunchingProvidersLocked(app, false)) {
14326            restart = true;
14327        }
14328
14329        // Unregister from connected content providers.
14330        if (!app.conProviders.isEmpty()) {
14331            for (int i=0; i<app.conProviders.size(); i++) {
14332                ContentProviderConnection conn = app.conProviders.get(i);
14333                conn.provider.connections.remove(conn);
14334            }
14335            app.conProviders.clear();
14336        }
14337
14338        // At this point there may be remaining entries in mLaunchingProviders
14339        // where we were the only one waiting, so they are no longer of use.
14340        // Look for these and clean up if found.
14341        // XXX Commented out for now.  Trying to figure out a way to reproduce
14342        // the actual situation to identify what is actually going on.
14343        if (false) {
14344            for (int i=0; i<mLaunchingProviders.size(); i++) {
14345                ContentProviderRecord cpr = (ContentProviderRecord)
14346                        mLaunchingProviders.get(i);
14347                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14348                    synchronized (cpr) {
14349                        cpr.launchingApp = null;
14350                        cpr.notifyAll();
14351                    }
14352                }
14353            }
14354        }
14355
14356        skipCurrentReceiverLocked(app);
14357
14358        // Unregister any receivers.
14359        for (int i=app.receivers.size()-1; i>=0; i--) {
14360            removeReceiverLocked(app.receivers.valueAt(i));
14361        }
14362        app.receivers.clear();
14363
14364        // If the app is undergoing backup, tell the backup manager about it
14365        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14366            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14367                    + mBackupTarget.appInfo + " died during backup");
14368            try {
14369                IBackupManager bm = IBackupManager.Stub.asInterface(
14370                        ServiceManager.getService(Context.BACKUP_SERVICE));
14371                bm.agentDisconnected(app.info.packageName);
14372            } catch (RemoteException e) {
14373                // can't happen; backup manager is local
14374            }
14375        }
14376
14377        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14378            ProcessChangeItem item = mPendingProcessChanges.get(i);
14379            if (item.pid == app.pid) {
14380                mPendingProcessChanges.remove(i);
14381                mAvailProcessChanges.add(item);
14382            }
14383        }
14384        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14385
14386        // If the caller is restarting this app, then leave it in its
14387        // current lists and let the caller take care of it.
14388        if (restarting) {
14389            return;
14390        }
14391
14392        if (!app.persistent || app.isolated) {
14393            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14394                    "Removing non-persistent process during cleanup: " + app);
14395            mProcessNames.remove(app.processName, app.uid);
14396            mIsolatedProcesses.remove(app.uid);
14397            if (mHeavyWeightProcess == app) {
14398                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14399                        mHeavyWeightProcess.userId, 0));
14400                mHeavyWeightProcess = null;
14401            }
14402        } else if (!app.removed) {
14403            // This app is persistent, so we need to keep its record around.
14404            // If it is not already on the pending app list, add it there
14405            // and start a new process for it.
14406            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14407                mPersistentStartingProcesses.add(app);
14408                restart = true;
14409            }
14410        }
14411        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14412                "Clean-up removing on hold: " + app);
14413        mProcessesOnHold.remove(app);
14414
14415        if (app == mHomeProcess) {
14416            mHomeProcess = null;
14417        }
14418        if (app == mPreviousProcess) {
14419            mPreviousProcess = null;
14420        }
14421
14422        if (restart && !app.isolated) {
14423            // We have components that still need to be running in the
14424            // process, so re-launch it.
14425            mProcessNames.put(app.processName, app.uid, app);
14426            startProcessLocked(app, "restart", app.processName);
14427        } else if (app.pid > 0 && app.pid != MY_PID) {
14428            // Goodbye!
14429            boolean removed;
14430            synchronized (mPidsSelfLocked) {
14431                mPidsSelfLocked.remove(app.pid);
14432                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14433            }
14434            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14435            if (app.isolated) {
14436                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14437            }
14438            app.setPid(0);
14439        }
14440    }
14441
14442    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14443        // Look through the content providers we are waiting to have launched,
14444        // and if any run in this process then either schedule a restart of
14445        // the process or kill the client waiting for it if this process has
14446        // gone bad.
14447        int NL = mLaunchingProviders.size();
14448        boolean restart = false;
14449        for (int i=0; i<NL; i++) {
14450            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14451            if (cpr.launchingApp == app) {
14452                if (!alwaysBad && !app.bad) {
14453                    restart = true;
14454                } else {
14455                    removeDyingProviderLocked(app, cpr, true);
14456                    // cpr should have been removed from mLaunchingProviders
14457                    NL = mLaunchingProviders.size();
14458                    i--;
14459                }
14460            }
14461        }
14462        return restart;
14463    }
14464
14465    // =========================================================
14466    // SERVICES
14467    // =========================================================
14468
14469    @Override
14470    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14471            int flags) {
14472        enforceNotIsolatedCaller("getServices");
14473        synchronized (this) {
14474            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14475        }
14476    }
14477
14478    @Override
14479    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14480        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14481        synchronized (this) {
14482            return mServices.getRunningServiceControlPanelLocked(name);
14483        }
14484    }
14485
14486    @Override
14487    public ComponentName startService(IApplicationThread caller, Intent service,
14488            String resolvedType, int userId) {
14489        enforceNotIsolatedCaller("startService");
14490        // Refuse possible leaked file descriptors
14491        if (service != null && service.hasFileDescriptors() == true) {
14492            throw new IllegalArgumentException("File descriptors passed in Intent");
14493        }
14494
14495        if (DEBUG_SERVICE)
14496            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14497        synchronized(this) {
14498            final int callingPid = Binder.getCallingPid();
14499            final int callingUid = Binder.getCallingUid();
14500            final long origId = Binder.clearCallingIdentity();
14501            ComponentName res = mServices.startServiceLocked(caller, service,
14502                    resolvedType, callingPid, callingUid, userId);
14503            Binder.restoreCallingIdentity(origId);
14504            return res;
14505        }
14506    }
14507
14508    ComponentName startServiceInPackage(int uid,
14509            Intent service, String resolvedType, int userId) {
14510        synchronized(this) {
14511            if (DEBUG_SERVICE)
14512                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14513            final long origId = Binder.clearCallingIdentity();
14514            ComponentName res = mServices.startServiceLocked(null, service,
14515                    resolvedType, -1, uid, userId);
14516            Binder.restoreCallingIdentity(origId);
14517            return res;
14518        }
14519    }
14520
14521    @Override
14522    public int stopService(IApplicationThread caller, Intent service,
14523            String resolvedType, int userId) {
14524        enforceNotIsolatedCaller("stopService");
14525        // Refuse possible leaked file descriptors
14526        if (service != null && service.hasFileDescriptors() == true) {
14527            throw new IllegalArgumentException("File descriptors passed in Intent");
14528        }
14529
14530        synchronized(this) {
14531            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14532        }
14533    }
14534
14535    @Override
14536    public IBinder peekService(Intent service, String resolvedType) {
14537        enforceNotIsolatedCaller("peekService");
14538        // Refuse possible leaked file descriptors
14539        if (service != null && service.hasFileDescriptors() == true) {
14540            throw new IllegalArgumentException("File descriptors passed in Intent");
14541        }
14542        synchronized(this) {
14543            return mServices.peekServiceLocked(service, resolvedType);
14544        }
14545    }
14546
14547    @Override
14548    public boolean stopServiceToken(ComponentName className, IBinder token,
14549            int startId) {
14550        synchronized(this) {
14551            return mServices.stopServiceTokenLocked(className, token, startId);
14552        }
14553    }
14554
14555    @Override
14556    public void setServiceForeground(ComponentName className, IBinder token,
14557            int id, Notification notification, boolean removeNotification) {
14558        synchronized(this) {
14559            mServices.setServiceForegroundLocked(className, token, id, notification,
14560                    removeNotification);
14561        }
14562    }
14563
14564    @Override
14565    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14566            boolean requireFull, String name, String callerPackage) {
14567        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14568                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14569    }
14570
14571    int unsafeConvertIncomingUser(int userId) {
14572        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14573                ? mCurrentUserId : userId;
14574    }
14575
14576    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14577            int allowMode, String name, String callerPackage) {
14578        final int callingUserId = UserHandle.getUserId(callingUid);
14579        if (callingUserId == userId) {
14580            return userId;
14581        }
14582
14583        // Note that we may be accessing mCurrentUserId outside of a lock...
14584        // shouldn't be a big deal, if this is being called outside
14585        // of a locked context there is intrinsically a race with
14586        // the value the caller will receive and someone else changing it.
14587        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14588        // we will switch to the calling user if access to the current user fails.
14589        int targetUserId = unsafeConvertIncomingUser(userId);
14590
14591        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14592            final boolean allow;
14593            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14594                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14595                // If the caller has this permission, they always pass go.  And collect $200.
14596                allow = true;
14597            } else if (allowMode == ALLOW_FULL_ONLY) {
14598                // We require full access, sucks to be you.
14599                allow = false;
14600            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14601                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14602                // If the caller does not have either permission, they are always doomed.
14603                allow = false;
14604            } else if (allowMode == ALLOW_NON_FULL) {
14605                // We are blanket allowing non-full access, you lucky caller!
14606                allow = true;
14607            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14608                // We may or may not allow this depending on whether the two users are
14609                // in the same profile.
14610                synchronized (mUserProfileGroupIdsSelfLocked) {
14611                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14612                            UserInfo.NO_PROFILE_GROUP_ID);
14613                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14614                            UserInfo.NO_PROFILE_GROUP_ID);
14615                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14616                            && callingProfile == targetProfile;
14617                }
14618            } else {
14619                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14620            }
14621            if (!allow) {
14622                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14623                    // In this case, they would like to just execute as their
14624                    // owner user instead of failing.
14625                    targetUserId = callingUserId;
14626                } else {
14627                    StringBuilder builder = new StringBuilder(128);
14628                    builder.append("Permission Denial: ");
14629                    builder.append(name);
14630                    if (callerPackage != null) {
14631                        builder.append(" from ");
14632                        builder.append(callerPackage);
14633                    }
14634                    builder.append(" asks to run as user ");
14635                    builder.append(userId);
14636                    builder.append(" but is calling from user ");
14637                    builder.append(UserHandle.getUserId(callingUid));
14638                    builder.append("; this requires ");
14639                    builder.append(INTERACT_ACROSS_USERS_FULL);
14640                    if (allowMode != ALLOW_FULL_ONLY) {
14641                        builder.append(" or ");
14642                        builder.append(INTERACT_ACROSS_USERS);
14643                    }
14644                    String msg = builder.toString();
14645                    Slog.w(TAG, msg);
14646                    throw new SecurityException(msg);
14647                }
14648            }
14649        }
14650        if (!allowAll && targetUserId < 0) {
14651            throw new IllegalArgumentException(
14652                    "Call does not support special user #" + targetUserId);
14653        }
14654        // Check shell permission
14655        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14656            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14657                    targetUserId)) {
14658                throw new SecurityException("Shell does not have permission to access user "
14659                        + targetUserId + "\n " + Debug.getCallers(3));
14660            }
14661        }
14662        return targetUserId;
14663    }
14664
14665    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14666            String className, int flags) {
14667        boolean result = false;
14668        // For apps that don't have pre-defined UIDs, check for permission
14669        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14670            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14671                if (ActivityManager.checkUidPermission(
14672                        INTERACT_ACROSS_USERS,
14673                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14674                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14675                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14676                            + " requests FLAG_SINGLE_USER, but app does not hold "
14677                            + INTERACT_ACROSS_USERS;
14678                    Slog.w(TAG, msg);
14679                    throw new SecurityException(msg);
14680                }
14681                // Permission passed
14682                result = true;
14683            }
14684        } else if ("system".equals(componentProcessName)) {
14685            result = true;
14686        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14687            // Phone app and persistent apps are allowed to export singleuser providers.
14688            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14689                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14690        }
14691        if (DEBUG_MU) {
14692            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14693                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14694        }
14695        return result;
14696    }
14697
14698    /**
14699     * Checks to see if the caller is in the same app as the singleton
14700     * component, or the component is in a special app. It allows special apps
14701     * to export singleton components but prevents exporting singleton
14702     * components for regular apps.
14703     */
14704    boolean isValidSingletonCall(int callingUid, int componentUid) {
14705        int componentAppId = UserHandle.getAppId(componentUid);
14706        return UserHandle.isSameApp(callingUid, componentUid)
14707                || componentAppId == Process.SYSTEM_UID
14708                || componentAppId == Process.PHONE_UID
14709                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14710                        == PackageManager.PERMISSION_GRANTED;
14711    }
14712
14713    public int bindService(IApplicationThread caller, IBinder token,
14714            Intent service, String resolvedType,
14715            IServiceConnection connection, int flags, int userId) {
14716        enforceNotIsolatedCaller("bindService");
14717
14718        // Refuse possible leaked file descriptors
14719        if (service != null && service.hasFileDescriptors() == true) {
14720            throw new IllegalArgumentException("File descriptors passed in Intent");
14721        }
14722
14723        synchronized(this) {
14724            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14725                    connection, flags, userId);
14726        }
14727    }
14728
14729    public boolean unbindService(IServiceConnection connection) {
14730        synchronized (this) {
14731            return mServices.unbindServiceLocked(connection);
14732        }
14733    }
14734
14735    public void publishService(IBinder token, Intent intent, IBinder service) {
14736        // Refuse possible leaked file descriptors
14737        if (intent != null && intent.hasFileDescriptors() == true) {
14738            throw new IllegalArgumentException("File descriptors passed in Intent");
14739        }
14740
14741        synchronized(this) {
14742            if (!(token instanceof ServiceRecord)) {
14743                throw new IllegalArgumentException("Invalid service token");
14744            }
14745            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14746        }
14747    }
14748
14749    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14750        // Refuse possible leaked file descriptors
14751        if (intent != null && intent.hasFileDescriptors() == true) {
14752            throw new IllegalArgumentException("File descriptors passed in Intent");
14753        }
14754
14755        synchronized(this) {
14756            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14757        }
14758    }
14759
14760    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14761        synchronized(this) {
14762            if (!(token instanceof ServiceRecord)) {
14763                throw new IllegalArgumentException("Invalid service token");
14764            }
14765            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14766        }
14767    }
14768
14769    // =========================================================
14770    // BACKUP AND RESTORE
14771    // =========================================================
14772
14773    // Cause the target app to be launched if necessary and its backup agent
14774    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14775    // activity manager to announce its creation.
14776    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14777        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14778        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14779
14780        synchronized(this) {
14781            // !!! TODO: currently no check here that we're already bound
14782            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14783            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14784            synchronized (stats) {
14785                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14786            }
14787
14788            // Backup agent is now in use, its package can't be stopped.
14789            try {
14790                AppGlobals.getPackageManager().setPackageStoppedState(
14791                        app.packageName, false, UserHandle.getUserId(app.uid));
14792            } catch (RemoteException e) {
14793            } catch (IllegalArgumentException e) {
14794                Slog.w(TAG, "Failed trying to unstop package "
14795                        + app.packageName + ": " + e);
14796            }
14797
14798            BackupRecord r = new BackupRecord(ss, app, backupMode);
14799            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14800                    ? new ComponentName(app.packageName, app.backupAgentName)
14801                    : new ComponentName("android", "FullBackupAgent");
14802            // startProcessLocked() returns existing proc's record if it's already running
14803            ProcessRecord proc = startProcessLocked(app.processName, app,
14804                    false, 0, "backup", hostingName, false, false, false);
14805            if (proc == null) {
14806                Slog.e(TAG, "Unable to start backup agent process " + r);
14807                return false;
14808            }
14809
14810            r.app = proc;
14811            mBackupTarget = r;
14812            mBackupAppName = app.packageName;
14813
14814            // Try not to kill the process during backup
14815            updateOomAdjLocked(proc);
14816
14817            // If the process is already attached, schedule the creation of the backup agent now.
14818            // If it is not yet live, this will be done when it attaches to the framework.
14819            if (proc.thread != null) {
14820                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14821                try {
14822                    proc.thread.scheduleCreateBackupAgent(app,
14823                            compatibilityInfoForPackageLocked(app), backupMode);
14824                } catch (RemoteException e) {
14825                    // Will time out on the backup manager side
14826                }
14827            } else {
14828                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14829            }
14830            // Invariants: at this point, the target app process exists and the application
14831            // is either already running or in the process of coming up.  mBackupTarget and
14832            // mBackupAppName describe the app, so that when it binds back to the AM we
14833            // know that it's scheduled for a backup-agent operation.
14834        }
14835
14836        return true;
14837    }
14838
14839    @Override
14840    public void clearPendingBackup() {
14841        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14842        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14843
14844        synchronized (this) {
14845            mBackupTarget = null;
14846            mBackupAppName = null;
14847        }
14848    }
14849
14850    // A backup agent has just come up
14851    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14852        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14853                + " = " + agent);
14854
14855        synchronized(this) {
14856            if (!agentPackageName.equals(mBackupAppName)) {
14857                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14858                return;
14859            }
14860        }
14861
14862        long oldIdent = Binder.clearCallingIdentity();
14863        try {
14864            IBackupManager bm = IBackupManager.Stub.asInterface(
14865                    ServiceManager.getService(Context.BACKUP_SERVICE));
14866            bm.agentConnected(agentPackageName, agent);
14867        } catch (RemoteException e) {
14868            // can't happen; the backup manager service is local
14869        } catch (Exception e) {
14870            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14871            e.printStackTrace();
14872        } finally {
14873            Binder.restoreCallingIdentity(oldIdent);
14874        }
14875    }
14876
14877    // done with this agent
14878    public void unbindBackupAgent(ApplicationInfo appInfo) {
14879        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14880        if (appInfo == null) {
14881            Slog.w(TAG, "unbind backup agent for null app");
14882            return;
14883        }
14884
14885        synchronized(this) {
14886            try {
14887                if (mBackupAppName == null) {
14888                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14889                    return;
14890                }
14891
14892                if (!mBackupAppName.equals(appInfo.packageName)) {
14893                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14894                    return;
14895                }
14896
14897                // Not backing this app up any more; reset its OOM adjustment
14898                final ProcessRecord proc = mBackupTarget.app;
14899                updateOomAdjLocked(proc);
14900
14901                // If the app crashed during backup, 'thread' will be null here
14902                if (proc.thread != null) {
14903                    try {
14904                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14905                                compatibilityInfoForPackageLocked(appInfo));
14906                    } catch (Exception e) {
14907                        Slog.e(TAG, "Exception when unbinding backup agent:");
14908                        e.printStackTrace();
14909                    }
14910                }
14911            } finally {
14912                mBackupTarget = null;
14913                mBackupAppName = null;
14914            }
14915        }
14916    }
14917    // =========================================================
14918    // BROADCASTS
14919    // =========================================================
14920
14921    private final List getStickiesLocked(String action, IntentFilter filter,
14922            List cur, int userId) {
14923        final ContentResolver resolver = mContext.getContentResolver();
14924        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14925        if (stickies == null) {
14926            return cur;
14927        }
14928        final ArrayList<Intent> list = stickies.get(action);
14929        if (list == null) {
14930            return cur;
14931        }
14932        int N = list.size();
14933        for (int i=0; i<N; i++) {
14934            Intent intent = list.get(i);
14935            if (filter.match(resolver, intent, true, TAG) >= 0) {
14936                if (cur == null) {
14937                    cur = new ArrayList<Intent>();
14938                }
14939                cur.add(intent);
14940            }
14941        }
14942        return cur;
14943    }
14944
14945    boolean isPendingBroadcastProcessLocked(int pid) {
14946        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14947                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14948    }
14949
14950    void skipPendingBroadcastLocked(int pid) {
14951            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14952            for (BroadcastQueue queue : mBroadcastQueues) {
14953                queue.skipPendingBroadcastLocked(pid);
14954            }
14955    }
14956
14957    // The app just attached; send any pending broadcasts that it should receive
14958    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14959        boolean didSomething = false;
14960        for (BroadcastQueue queue : mBroadcastQueues) {
14961            didSomething |= queue.sendPendingBroadcastsLocked(app);
14962        }
14963        return didSomething;
14964    }
14965
14966    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14967            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14968        enforceNotIsolatedCaller("registerReceiver");
14969        int callingUid;
14970        int callingPid;
14971        synchronized(this) {
14972            ProcessRecord callerApp = null;
14973            if (caller != null) {
14974                callerApp = getRecordForAppLocked(caller);
14975                if (callerApp == null) {
14976                    throw new SecurityException(
14977                            "Unable to find app for caller " + caller
14978                            + " (pid=" + Binder.getCallingPid()
14979                            + ") when registering receiver " + receiver);
14980                }
14981                if (callerApp.info.uid != Process.SYSTEM_UID &&
14982                        !callerApp.pkgList.containsKey(callerPackage) &&
14983                        !"android".equals(callerPackage)) {
14984                    throw new SecurityException("Given caller package " + callerPackage
14985                            + " is not running in process " + callerApp);
14986                }
14987                callingUid = callerApp.info.uid;
14988                callingPid = callerApp.pid;
14989            } else {
14990                callerPackage = null;
14991                callingUid = Binder.getCallingUid();
14992                callingPid = Binder.getCallingPid();
14993            }
14994
14995            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14996                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14997
14998            List allSticky = null;
14999
15000            // Look for any matching sticky broadcasts...
15001            Iterator actions = filter.actionsIterator();
15002            if (actions != null) {
15003                while (actions.hasNext()) {
15004                    String action = (String)actions.next();
15005                    allSticky = getStickiesLocked(action, filter, allSticky,
15006                            UserHandle.USER_ALL);
15007                    allSticky = getStickiesLocked(action, filter, allSticky,
15008                            UserHandle.getUserId(callingUid));
15009                }
15010            } else {
15011                allSticky = getStickiesLocked(null, filter, allSticky,
15012                        UserHandle.USER_ALL);
15013                allSticky = getStickiesLocked(null, filter, allSticky,
15014                        UserHandle.getUserId(callingUid));
15015            }
15016
15017            // The first sticky in the list is returned directly back to
15018            // the client.
15019            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15020
15021            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15022                    + ": " + sticky);
15023
15024            if (receiver == null) {
15025                return sticky;
15026            }
15027
15028            ReceiverList rl
15029                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15030            if (rl == null) {
15031                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15032                        userId, receiver);
15033                if (rl.app != null) {
15034                    rl.app.receivers.add(rl);
15035                } else {
15036                    try {
15037                        receiver.asBinder().linkToDeath(rl, 0);
15038                    } catch (RemoteException e) {
15039                        return sticky;
15040                    }
15041                    rl.linkedToDeath = true;
15042                }
15043                mRegisteredReceivers.put(receiver.asBinder(), rl);
15044            } else if (rl.uid != callingUid) {
15045                throw new IllegalArgumentException(
15046                        "Receiver requested to register for uid " + callingUid
15047                        + " was previously registered for uid " + rl.uid);
15048            } else if (rl.pid != callingPid) {
15049                throw new IllegalArgumentException(
15050                        "Receiver requested to register for pid " + callingPid
15051                        + " was previously registered for pid " + rl.pid);
15052            } else if (rl.userId != userId) {
15053                throw new IllegalArgumentException(
15054                        "Receiver requested to register for user " + userId
15055                        + " was previously registered for user " + rl.userId);
15056            }
15057            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15058                    permission, callingUid, userId);
15059            rl.add(bf);
15060            if (!bf.debugCheck()) {
15061                Slog.w(TAG, "==> For Dynamic broadast");
15062            }
15063            mReceiverResolver.addFilter(bf);
15064
15065            // Enqueue broadcasts for all existing stickies that match
15066            // this filter.
15067            if (allSticky != null) {
15068                ArrayList receivers = new ArrayList();
15069                receivers.add(bf);
15070
15071                int N = allSticky.size();
15072                for (int i=0; i<N; i++) {
15073                    Intent intent = (Intent)allSticky.get(i);
15074                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15075                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15076                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15077                            null, null, false, true, true, -1);
15078                    queue.enqueueParallelBroadcastLocked(r);
15079                    queue.scheduleBroadcastsLocked();
15080                }
15081            }
15082
15083            return sticky;
15084        }
15085    }
15086
15087    public void unregisterReceiver(IIntentReceiver receiver) {
15088        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15089
15090        final long origId = Binder.clearCallingIdentity();
15091        try {
15092            boolean doTrim = false;
15093
15094            synchronized(this) {
15095                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15096                if (rl != null) {
15097                    if (rl.curBroadcast != null) {
15098                        BroadcastRecord r = rl.curBroadcast;
15099                        final boolean doNext = finishReceiverLocked(
15100                                receiver.asBinder(), r.resultCode, r.resultData,
15101                                r.resultExtras, r.resultAbort);
15102                        if (doNext) {
15103                            doTrim = true;
15104                            r.queue.processNextBroadcast(false);
15105                        }
15106                    }
15107
15108                    if (rl.app != null) {
15109                        rl.app.receivers.remove(rl);
15110                    }
15111                    removeReceiverLocked(rl);
15112                    if (rl.linkedToDeath) {
15113                        rl.linkedToDeath = false;
15114                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15115                    }
15116                }
15117            }
15118
15119            // If we actually concluded any broadcasts, we might now be able
15120            // to trim the recipients' apps from our working set
15121            if (doTrim) {
15122                trimApplications();
15123                return;
15124            }
15125
15126        } finally {
15127            Binder.restoreCallingIdentity(origId);
15128        }
15129    }
15130
15131    void removeReceiverLocked(ReceiverList rl) {
15132        mRegisteredReceivers.remove(rl.receiver.asBinder());
15133        int N = rl.size();
15134        for (int i=0; i<N; i++) {
15135            mReceiverResolver.removeFilter(rl.get(i));
15136        }
15137    }
15138
15139    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15140        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15141            ProcessRecord r = mLruProcesses.get(i);
15142            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15143                try {
15144                    r.thread.dispatchPackageBroadcast(cmd, packages);
15145                } catch (RemoteException ex) {
15146                }
15147            }
15148        }
15149    }
15150
15151    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15152            int callingUid, int[] users) {
15153        List<ResolveInfo> receivers = null;
15154        try {
15155            HashSet<ComponentName> singleUserReceivers = null;
15156            boolean scannedFirstReceivers = false;
15157            for (int user : users) {
15158                // Skip users that have Shell restrictions
15159                if (callingUid == Process.SHELL_UID
15160                        && getUserManagerLocked().hasUserRestriction(
15161                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15162                    continue;
15163                }
15164                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15165                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15166                if (user != 0 && newReceivers != null) {
15167                    // If this is not the primary user, we need to check for
15168                    // any receivers that should be filtered out.
15169                    for (int i=0; i<newReceivers.size(); i++) {
15170                        ResolveInfo ri = newReceivers.get(i);
15171                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15172                            newReceivers.remove(i);
15173                            i--;
15174                        }
15175                    }
15176                }
15177                if (newReceivers != null && newReceivers.size() == 0) {
15178                    newReceivers = null;
15179                }
15180                if (receivers == null) {
15181                    receivers = newReceivers;
15182                } else if (newReceivers != null) {
15183                    // We need to concatenate the additional receivers
15184                    // found with what we have do far.  This would be easy,
15185                    // but we also need to de-dup any receivers that are
15186                    // singleUser.
15187                    if (!scannedFirstReceivers) {
15188                        // Collect any single user receivers we had already retrieved.
15189                        scannedFirstReceivers = true;
15190                        for (int i=0; i<receivers.size(); i++) {
15191                            ResolveInfo ri = receivers.get(i);
15192                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15193                                ComponentName cn = new ComponentName(
15194                                        ri.activityInfo.packageName, ri.activityInfo.name);
15195                                if (singleUserReceivers == null) {
15196                                    singleUserReceivers = new HashSet<ComponentName>();
15197                                }
15198                                singleUserReceivers.add(cn);
15199                            }
15200                        }
15201                    }
15202                    // Add the new results to the existing results, tracking
15203                    // and de-dupping single user receivers.
15204                    for (int i=0; i<newReceivers.size(); i++) {
15205                        ResolveInfo ri = newReceivers.get(i);
15206                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15207                            ComponentName cn = new ComponentName(
15208                                    ri.activityInfo.packageName, ri.activityInfo.name);
15209                            if (singleUserReceivers == null) {
15210                                singleUserReceivers = new HashSet<ComponentName>();
15211                            }
15212                            if (!singleUserReceivers.contains(cn)) {
15213                                singleUserReceivers.add(cn);
15214                                receivers.add(ri);
15215                            }
15216                        } else {
15217                            receivers.add(ri);
15218                        }
15219                    }
15220                }
15221            }
15222        } catch (RemoteException ex) {
15223            // pm is in same process, this will never happen.
15224        }
15225        return receivers;
15226    }
15227
15228    private final int broadcastIntentLocked(ProcessRecord callerApp,
15229            String callerPackage, Intent intent, String resolvedType,
15230            IIntentReceiver resultTo, int resultCode, String resultData,
15231            Bundle map, String requiredPermission, int appOp,
15232            boolean ordered, boolean sticky, int callingPid, int callingUid,
15233            int userId) {
15234        intent = new Intent(intent);
15235
15236        // By default broadcasts do not go to stopped apps.
15237        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15238
15239        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15240            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15241            + " ordered=" + ordered + " userid=" + userId);
15242        if ((resultTo != null) && !ordered) {
15243            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15244        }
15245
15246        userId = handleIncomingUser(callingPid, callingUid, userId,
15247                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15248
15249        // Make sure that the user who is receiving this broadcast is started.
15250        // If not, we will just skip it.
15251
15252        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15253            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15254                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15255                Slog.w(TAG, "Skipping broadcast of " + intent
15256                        + ": user " + userId + " is stopped");
15257                return ActivityManager.BROADCAST_SUCCESS;
15258            }
15259        }
15260
15261        /*
15262         * Prevent non-system code (defined here to be non-persistent
15263         * processes) from sending protected broadcasts.
15264         */
15265        int callingAppId = UserHandle.getAppId(callingUid);
15266        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15267            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15268            || callingAppId == Process.NFC_UID || callingUid == 0) {
15269            // Always okay.
15270        } else if (callerApp == null || !callerApp.persistent) {
15271            try {
15272                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15273                        intent.getAction())) {
15274                    String msg = "Permission Denial: not allowed to send broadcast "
15275                            + intent.getAction() + " from pid="
15276                            + callingPid + ", uid=" + callingUid;
15277                    Slog.w(TAG, msg);
15278                    throw new SecurityException(msg);
15279                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15280                    // Special case for compatibility: we don't want apps to send this,
15281                    // but historically it has not been protected and apps may be using it
15282                    // to poke their own app widget.  So, instead of making it protected,
15283                    // just limit it to the caller.
15284                    if (callerApp == null) {
15285                        String msg = "Permission Denial: not allowed to send broadcast "
15286                                + intent.getAction() + " from unknown caller.";
15287                        Slog.w(TAG, msg);
15288                        throw new SecurityException(msg);
15289                    } else if (intent.getComponent() != null) {
15290                        // They are good enough to send to an explicit component...  verify
15291                        // it is being sent to the calling app.
15292                        if (!intent.getComponent().getPackageName().equals(
15293                                callerApp.info.packageName)) {
15294                            String msg = "Permission Denial: not allowed to send broadcast "
15295                                    + intent.getAction() + " to "
15296                                    + intent.getComponent().getPackageName() + " from "
15297                                    + callerApp.info.packageName;
15298                            Slog.w(TAG, msg);
15299                            throw new SecurityException(msg);
15300                        }
15301                    } else {
15302                        // Limit broadcast to their own package.
15303                        intent.setPackage(callerApp.info.packageName);
15304                    }
15305                }
15306            } catch (RemoteException e) {
15307                Slog.w(TAG, "Remote exception", e);
15308                return ActivityManager.BROADCAST_SUCCESS;
15309            }
15310        }
15311
15312        // Handle special intents: if this broadcast is from the package
15313        // manager about a package being removed, we need to remove all of
15314        // its activities from the history stack.
15315        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15316                intent.getAction());
15317        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15318                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15319                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15320                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15321                || uidRemoved) {
15322            if (checkComponentPermission(
15323                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15324                    callingPid, callingUid, -1, true)
15325                    == PackageManager.PERMISSION_GRANTED) {
15326                if (uidRemoved) {
15327                    final Bundle intentExtras = intent.getExtras();
15328                    final int uid = intentExtras != null
15329                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15330                    if (uid >= 0) {
15331                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15332                        synchronized (bs) {
15333                            bs.removeUidStatsLocked(uid);
15334                        }
15335                        mAppOpsService.uidRemoved(uid);
15336                    }
15337                } else {
15338                    // If resources are unavailable just force stop all
15339                    // those packages and flush the attribute cache as well.
15340                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15341                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15342                        if (list != null && (list.length > 0)) {
15343                            for (String pkg : list) {
15344                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15345                                        "storage unmount");
15346                            }
15347                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15348                            sendPackageBroadcastLocked(
15349                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15350                        }
15351                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15352                            intent.getAction())) {
15353                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15354                    } else {
15355                        Uri data = intent.getData();
15356                        String ssp;
15357                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15358                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15359                                    intent.getAction());
15360                            boolean fullUninstall = removed &&
15361                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15362                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15363                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15364                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15365                                        false, fullUninstall, userId,
15366                                        removed ? "pkg removed" : "pkg changed");
15367                            }
15368                            if (removed) {
15369                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15370                                        new String[] {ssp}, userId);
15371                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15372                                    mAppOpsService.packageRemoved(
15373                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15374
15375                                    // Remove all permissions granted from/to this package
15376                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15377                                }
15378                            }
15379                        }
15380                    }
15381                }
15382            } else {
15383                String msg = "Permission Denial: " + intent.getAction()
15384                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15385                        + ", uid=" + callingUid + ")"
15386                        + " requires "
15387                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15388                Slog.w(TAG, msg);
15389                throw new SecurityException(msg);
15390            }
15391
15392        // Special case for adding a package: by default turn on compatibility
15393        // mode.
15394        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15395            Uri data = intent.getData();
15396            String ssp;
15397            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15398                mCompatModePackages.handlePackageAddedLocked(ssp,
15399                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15400            }
15401        }
15402
15403        /*
15404         * If this is the time zone changed action, queue up a message that will reset the timezone
15405         * of all currently running processes. This message will get queued up before the broadcast
15406         * happens.
15407         */
15408        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15409            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15410        }
15411
15412        /*
15413         * If the user set the time, let all running processes know.
15414         */
15415        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15416            final int is24Hour = intent.getBooleanExtra(
15417                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15418            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15419            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15420            synchronized (stats) {
15421                stats.noteCurrentTimeChangedLocked();
15422            }
15423        }
15424
15425        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15426            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15427        }
15428
15429        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15430            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15431            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15432        }
15433
15434        // Add to the sticky list if requested.
15435        if (sticky) {
15436            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15437                    callingPid, callingUid)
15438                    != PackageManager.PERMISSION_GRANTED) {
15439                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15440                        + callingPid + ", uid=" + callingUid
15441                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15442                Slog.w(TAG, msg);
15443                throw new SecurityException(msg);
15444            }
15445            if (requiredPermission != null) {
15446                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15447                        + " and enforce permission " + requiredPermission);
15448                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15449            }
15450            if (intent.getComponent() != null) {
15451                throw new SecurityException(
15452                        "Sticky broadcasts can't target a specific component");
15453            }
15454            // We use userId directly here, since the "all" target is maintained
15455            // as a separate set of sticky broadcasts.
15456            if (userId != UserHandle.USER_ALL) {
15457                // But first, if this is not a broadcast to all users, then
15458                // make sure it doesn't conflict with an existing broadcast to
15459                // all users.
15460                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15461                        UserHandle.USER_ALL);
15462                if (stickies != null) {
15463                    ArrayList<Intent> list = stickies.get(intent.getAction());
15464                    if (list != null) {
15465                        int N = list.size();
15466                        int i;
15467                        for (i=0; i<N; i++) {
15468                            if (intent.filterEquals(list.get(i))) {
15469                                throw new IllegalArgumentException(
15470                                        "Sticky broadcast " + intent + " for user "
15471                                        + userId + " conflicts with existing global broadcast");
15472                            }
15473                        }
15474                    }
15475                }
15476            }
15477            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15478            if (stickies == null) {
15479                stickies = new ArrayMap<String, ArrayList<Intent>>();
15480                mStickyBroadcasts.put(userId, stickies);
15481            }
15482            ArrayList<Intent> list = stickies.get(intent.getAction());
15483            if (list == null) {
15484                list = new ArrayList<Intent>();
15485                stickies.put(intent.getAction(), list);
15486            }
15487            int N = list.size();
15488            int i;
15489            for (i=0; i<N; i++) {
15490                if (intent.filterEquals(list.get(i))) {
15491                    // This sticky already exists, replace it.
15492                    list.set(i, new Intent(intent));
15493                    break;
15494                }
15495            }
15496            if (i >= N) {
15497                list.add(new Intent(intent));
15498            }
15499        }
15500
15501        int[] users;
15502        if (userId == UserHandle.USER_ALL) {
15503            // Caller wants broadcast to go to all started users.
15504            users = mStartedUserArray;
15505        } else {
15506            // Caller wants broadcast to go to one specific user.
15507            users = new int[] {userId};
15508        }
15509
15510        // Figure out who all will receive this broadcast.
15511        List receivers = null;
15512        List<BroadcastFilter> registeredReceivers = null;
15513        // Need to resolve the intent to interested receivers...
15514        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15515                 == 0) {
15516            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15517        }
15518        if (intent.getComponent() == null) {
15519            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15520                // Query one target user at a time, excluding shell-restricted users
15521                UserManagerService ums = getUserManagerLocked();
15522                for (int i = 0; i < users.length; i++) {
15523                    if (ums.hasUserRestriction(
15524                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15525                        continue;
15526                    }
15527                    List<BroadcastFilter> registeredReceiversForUser =
15528                            mReceiverResolver.queryIntent(intent,
15529                                    resolvedType, false, users[i]);
15530                    if (registeredReceivers == null) {
15531                        registeredReceivers = registeredReceiversForUser;
15532                    } else if (registeredReceiversForUser != null) {
15533                        registeredReceivers.addAll(registeredReceiversForUser);
15534                    }
15535                }
15536            } else {
15537                registeredReceivers = mReceiverResolver.queryIntent(intent,
15538                        resolvedType, false, userId);
15539            }
15540        }
15541
15542        final boolean replacePending =
15543                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15544
15545        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15546                + " replacePending=" + replacePending);
15547
15548        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15549        if (!ordered && NR > 0) {
15550            // If we are not serializing this broadcast, then send the
15551            // registered receivers separately so they don't wait for the
15552            // components to be launched.
15553            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15554            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15555                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15556                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15557                    ordered, sticky, false, userId);
15558            if (DEBUG_BROADCAST) Slog.v(
15559                    TAG, "Enqueueing parallel broadcast " + r);
15560            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15561            if (!replaced) {
15562                queue.enqueueParallelBroadcastLocked(r);
15563                queue.scheduleBroadcastsLocked();
15564            }
15565            registeredReceivers = null;
15566            NR = 0;
15567        }
15568
15569        // Merge into one list.
15570        int ir = 0;
15571        if (receivers != null) {
15572            // A special case for PACKAGE_ADDED: do not allow the package
15573            // being added to see this broadcast.  This prevents them from
15574            // using this as a back door to get run as soon as they are
15575            // installed.  Maybe in the future we want to have a special install
15576            // broadcast or such for apps, but we'd like to deliberately make
15577            // this decision.
15578            String skipPackages[] = null;
15579            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15580                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15581                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15582                Uri data = intent.getData();
15583                if (data != null) {
15584                    String pkgName = data.getSchemeSpecificPart();
15585                    if (pkgName != null) {
15586                        skipPackages = new String[] { pkgName };
15587                    }
15588                }
15589            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15590                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15591            }
15592            if (skipPackages != null && (skipPackages.length > 0)) {
15593                for (String skipPackage : skipPackages) {
15594                    if (skipPackage != null) {
15595                        int NT = receivers.size();
15596                        for (int it=0; it<NT; it++) {
15597                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15598                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15599                                receivers.remove(it);
15600                                it--;
15601                                NT--;
15602                            }
15603                        }
15604                    }
15605                }
15606            }
15607
15608            int NT = receivers != null ? receivers.size() : 0;
15609            int it = 0;
15610            ResolveInfo curt = null;
15611            BroadcastFilter curr = null;
15612            while (it < NT && ir < NR) {
15613                if (curt == null) {
15614                    curt = (ResolveInfo)receivers.get(it);
15615                }
15616                if (curr == null) {
15617                    curr = registeredReceivers.get(ir);
15618                }
15619                if (curr.getPriority() >= curt.priority) {
15620                    // Insert this broadcast record into the final list.
15621                    receivers.add(it, curr);
15622                    ir++;
15623                    curr = null;
15624                    it++;
15625                    NT++;
15626                } else {
15627                    // Skip to the next ResolveInfo in the final list.
15628                    it++;
15629                    curt = null;
15630                }
15631            }
15632        }
15633        while (ir < NR) {
15634            if (receivers == null) {
15635                receivers = new ArrayList();
15636            }
15637            receivers.add(registeredReceivers.get(ir));
15638            ir++;
15639        }
15640
15641        if ((receivers != null && receivers.size() > 0)
15642                || resultTo != null) {
15643            BroadcastQueue queue = broadcastQueueForIntent(intent);
15644            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15645                    callerPackage, callingPid, callingUid, resolvedType,
15646                    requiredPermission, appOp, receivers, resultTo, resultCode,
15647                    resultData, map, ordered, sticky, false, userId);
15648            if (DEBUG_BROADCAST) Slog.v(
15649                    TAG, "Enqueueing ordered broadcast " + r
15650                    + ": prev had " + queue.mOrderedBroadcasts.size());
15651            if (DEBUG_BROADCAST) {
15652                int seq = r.intent.getIntExtra("seq", -1);
15653                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15654            }
15655            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15656            if (!replaced) {
15657                queue.enqueueOrderedBroadcastLocked(r);
15658                queue.scheduleBroadcastsLocked();
15659            }
15660        }
15661
15662        return ActivityManager.BROADCAST_SUCCESS;
15663    }
15664
15665    final Intent verifyBroadcastLocked(Intent intent) {
15666        // Refuse possible leaked file descriptors
15667        if (intent != null && intent.hasFileDescriptors() == true) {
15668            throw new IllegalArgumentException("File descriptors passed in Intent");
15669        }
15670
15671        int flags = intent.getFlags();
15672
15673        if (!mProcessesReady) {
15674            // if the caller really truly claims to know what they're doing, go
15675            // ahead and allow the broadcast without launching any receivers
15676            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15677                intent = new Intent(intent);
15678                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15679            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15680                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15681                        + " before boot completion");
15682                throw new IllegalStateException("Cannot broadcast before boot completed");
15683            }
15684        }
15685
15686        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15687            throw new IllegalArgumentException(
15688                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15689        }
15690
15691        return intent;
15692    }
15693
15694    public final int broadcastIntent(IApplicationThread caller,
15695            Intent intent, String resolvedType, IIntentReceiver resultTo,
15696            int resultCode, String resultData, Bundle map,
15697            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15698        enforceNotIsolatedCaller("broadcastIntent");
15699        synchronized(this) {
15700            intent = verifyBroadcastLocked(intent);
15701
15702            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15703            final int callingPid = Binder.getCallingPid();
15704            final int callingUid = Binder.getCallingUid();
15705            final long origId = Binder.clearCallingIdentity();
15706            int res = broadcastIntentLocked(callerApp,
15707                    callerApp != null ? callerApp.info.packageName : null,
15708                    intent, resolvedType, resultTo,
15709                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15710                    callingPid, callingUid, userId);
15711            Binder.restoreCallingIdentity(origId);
15712            return res;
15713        }
15714    }
15715
15716    int broadcastIntentInPackage(String packageName, int uid,
15717            Intent intent, String resolvedType, IIntentReceiver resultTo,
15718            int resultCode, String resultData, Bundle map,
15719            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15720        synchronized(this) {
15721            intent = verifyBroadcastLocked(intent);
15722
15723            final long origId = Binder.clearCallingIdentity();
15724            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15725                    resultTo, resultCode, resultData, map, requiredPermission,
15726                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15727            Binder.restoreCallingIdentity(origId);
15728            return res;
15729        }
15730    }
15731
15732    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15733        // Refuse possible leaked file descriptors
15734        if (intent != null && intent.hasFileDescriptors() == true) {
15735            throw new IllegalArgumentException("File descriptors passed in Intent");
15736        }
15737
15738        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15739                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15740
15741        synchronized(this) {
15742            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15743                    != PackageManager.PERMISSION_GRANTED) {
15744                String msg = "Permission Denial: unbroadcastIntent() from pid="
15745                        + Binder.getCallingPid()
15746                        + ", uid=" + Binder.getCallingUid()
15747                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15748                Slog.w(TAG, msg);
15749                throw new SecurityException(msg);
15750            }
15751            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15752            if (stickies != null) {
15753                ArrayList<Intent> list = stickies.get(intent.getAction());
15754                if (list != null) {
15755                    int N = list.size();
15756                    int i;
15757                    for (i=0; i<N; i++) {
15758                        if (intent.filterEquals(list.get(i))) {
15759                            list.remove(i);
15760                            break;
15761                        }
15762                    }
15763                    if (list.size() <= 0) {
15764                        stickies.remove(intent.getAction());
15765                    }
15766                }
15767                if (stickies.size() <= 0) {
15768                    mStickyBroadcasts.remove(userId);
15769                }
15770            }
15771        }
15772    }
15773
15774    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15775            String resultData, Bundle resultExtras, boolean resultAbort) {
15776        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15777        if (r == null) {
15778            Slog.w(TAG, "finishReceiver called but not found on queue");
15779            return false;
15780        }
15781
15782        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15783    }
15784
15785    void backgroundServicesFinishedLocked(int userId) {
15786        for (BroadcastQueue queue : mBroadcastQueues) {
15787            queue.backgroundServicesFinishedLocked(userId);
15788        }
15789    }
15790
15791    public void finishReceiver(IBinder who, int resultCode, String resultData,
15792            Bundle resultExtras, boolean resultAbort) {
15793        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15794
15795        // Refuse possible leaked file descriptors
15796        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15797            throw new IllegalArgumentException("File descriptors passed in Bundle");
15798        }
15799
15800        final long origId = Binder.clearCallingIdentity();
15801        try {
15802            boolean doNext = false;
15803            BroadcastRecord r;
15804
15805            synchronized(this) {
15806                r = broadcastRecordForReceiverLocked(who);
15807                if (r != null) {
15808                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15809                        resultData, resultExtras, resultAbort, true);
15810                }
15811            }
15812
15813            if (doNext) {
15814                r.queue.processNextBroadcast(false);
15815            }
15816            trimApplications();
15817        } finally {
15818            Binder.restoreCallingIdentity(origId);
15819        }
15820    }
15821
15822    // =========================================================
15823    // INSTRUMENTATION
15824    // =========================================================
15825
15826    public boolean startInstrumentation(ComponentName className,
15827            String profileFile, int flags, Bundle arguments,
15828            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15829            int userId, String abiOverride) {
15830        enforceNotIsolatedCaller("startInstrumentation");
15831        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15832                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15833        // Refuse possible leaked file descriptors
15834        if (arguments != null && arguments.hasFileDescriptors()) {
15835            throw new IllegalArgumentException("File descriptors passed in Bundle");
15836        }
15837
15838        synchronized(this) {
15839            InstrumentationInfo ii = null;
15840            ApplicationInfo ai = null;
15841            try {
15842                ii = mContext.getPackageManager().getInstrumentationInfo(
15843                    className, STOCK_PM_FLAGS);
15844                ai = AppGlobals.getPackageManager().getApplicationInfo(
15845                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15846            } catch (PackageManager.NameNotFoundException e) {
15847            } catch (RemoteException e) {
15848            }
15849            if (ii == null) {
15850                reportStartInstrumentationFailure(watcher, className,
15851                        "Unable to find instrumentation info for: " + className);
15852                return false;
15853            }
15854            if (ai == null) {
15855                reportStartInstrumentationFailure(watcher, className,
15856                        "Unable to find instrumentation target package: " + ii.targetPackage);
15857                return false;
15858            }
15859
15860            int match = mContext.getPackageManager().checkSignatures(
15861                    ii.targetPackage, ii.packageName);
15862            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15863                String msg = "Permission Denial: starting instrumentation "
15864                        + className + " from pid="
15865                        + Binder.getCallingPid()
15866                        + ", uid=" + Binder.getCallingPid()
15867                        + " not allowed because package " + ii.packageName
15868                        + " does not have a signature matching the target "
15869                        + ii.targetPackage;
15870                reportStartInstrumentationFailure(watcher, className, msg);
15871                throw new SecurityException(msg);
15872            }
15873
15874            final long origId = Binder.clearCallingIdentity();
15875            // Instrumentation can kill and relaunch even persistent processes
15876            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15877                    "start instr");
15878            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15879            app.instrumentationClass = className;
15880            app.instrumentationInfo = ai;
15881            app.instrumentationProfileFile = profileFile;
15882            app.instrumentationArguments = arguments;
15883            app.instrumentationWatcher = watcher;
15884            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15885            app.instrumentationResultClass = className;
15886            Binder.restoreCallingIdentity(origId);
15887        }
15888
15889        return true;
15890    }
15891
15892    /**
15893     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15894     * error to the logs, but if somebody is watching, send the report there too.  This enables
15895     * the "am" command to report errors with more information.
15896     *
15897     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15898     * @param cn The component name of the instrumentation.
15899     * @param report The error report.
15900     */
15901    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15902            ComponentName cn, String report) {
15903        Slog.w(TAG, report);
15904        try {
15905            if (watcher != null) {
15906                Bundle results = new Bundle();
15907                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15908                results.putString("Error", report);
15909                watcher.instrumentationStatus(cn, -1, results);
15910            }
15911        } catch (RemoteException e) {
15912            Slog.w(TAG, e);
15913        }
15914    }
15915
15916    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15917        if (app.instrumentationWatcher != null) {
15918            try {
15919                // NOTE:  IInstrumentationWatcher *must* be oneway here
15920                app.instrumentationWatcher.instrumentationFinished(
15921                    app.instrumentationClass,
15922                    resultCode,
15923                    results);
15924            } catch (RemoteException e) {
15925            }
15926        }
15927        if (app.instrumentationUiAutomationConnection != null) {
15928            try {
15929                app.instrumentationUiAutomationConnection.shutdown();
15930            } catch (RemoteException re) {
15931                /* ignore */
15932            }
15933            // Only a UiAutomation can set this flag and now that
15934            // it is finished we make sure it is reset to its default.
15935            mUserIsMonkey = false;
15936        }
15937        app.instrumentationWatcher = null;
15938        app.instrumentationUiAutomationConnection = null;
15939        app.instrumentationClass = null;
15940        app.instrumentationInfo = null;
15941        app.instrumentationProfileFile = null;
15942        app.instrumentationArguments = null;
15943
15944        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15945                "finished inst");
15946    }
15947
15948    public void finishInstrumentation(IApplicationThread target,
15949            int resultCode, Bundle results) {
15950        int userId = UserHandle.getCallingUserId();
15951        // Refuse possible leaked file descriptors
15952        if (results != null && results.hasFileDescriptors()) {
15953            throw new IllegalArgumentException("File descriptors passed in Intent");
15954        }
15955
15956        synchronized(this) {
15957            ProcessRecord app = getRecordForAppLocked(target);
15958            if (app == null) {
15959                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15960                return;
15961            }
15962            final long origId = Binder.clearCallingIdentity();
15963            finishInstrumentationLocked(app, resultCode, results);
15964            Binder.restoreCallingIdentity(origId);
15965        }
15966    }
15967
15968    // =========================================================
15969    // CONFIGURATION
15970    // =========================================================
15971
15972    public ConfigurationInfo getDeviceConfigurationInfo() {
15973        ConfigurationInfo config = new ConfigurationInfo();
15974        synchronized (this) {
15975            config.reqTouchScreen = mConfiguration.touchscreen;
15976            config.reqKeyboardType = mConfiguration.keyboard;
15977            config.reqNavigation = mConfiguration.navigation;
15978            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15979                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15980                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15981            }
15982            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15983                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15984                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15985            }
15986            config.reqGlEsVersion = GL_ES_VERSION;
15987        }
15988        return config;
15989    }
15990
15991    ActivityStack getFocusedStack() {
15992        return mStackSupervisor.getFocusedStack();
15993    }
15994
15995    public Configuration getConfiguration() {
15996        Configuration ci;
15997        synchronized(this) {
15998            ci = new Configuration(mConfiguration);
15999        }
16000        return ci;
16001    }
16002
16003    public void updatePersistentConfiguration(Configuration values) {
16004        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16005                "updateConfiguration()");
16006        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16007                "updateConfiguration()");
16008        if (values == null) {
16009            throw new NullPointerException("Configuration must not be null");
16010        }
16011
16012        synchronized(this) {
16013            final long origId = Binder.clearCallingIdentity();
16014            updateConfigurationLocked(values, null, true, false);
16015            Binder.restoreCallingIdentity(origId);
16016        }
16017    }
16018
16019    public void updateConfiguration(Configuration values) {
16020        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16021                "updateConfiguration()");
16022
16023        synchronized(this) {
16024            if (values == null && mWindowManager != null) {
16025                // sentinel: fetch the current configuration from the window manager
16026                values = mWindowManager.computeNewConfiguration();
16027            }
16028
16029            if (mWindowManager != null) {
16030                mProcessList.applyDisplaySize(mWindowManager);
16031            }
16032
16033            final long origId = Binder.clearCallingIdentity();
16034            if (values != null) {
16035                Settings.System.clearConfiguration(values);
16036            }
16037            updateConfigurationLocked(values, null, false, false);
16038            Binder.restoreCallingIdentity(origId);
16039        }
16040    }
16041
16042    /**
16043     * Do either or both things: (1) change the current configuration, and (2)
16044     * make sure the given activity is running with the (now) current
16045     * configuration.  Returns true if the activity has been left running, or
16046     * false if <var>starting</var> is being destroyed to match the new
16047     * configuration.
16048     * @param persistent TODO
16049     */
16050    boolean updateConfigurationLocked(Configuration values,
16051            ActivityRecord starting, boolean persistent, boolean initLocale) {
16052        int changes = 0;
16053
16054        if (values != null) {
16055            Configuration newConfig = new Configuration(mConfiguration);
16056            changes = newConfig.updateFrom(values);
16057            if (changes != 0) {
16058                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16059                    Slog.i(TAG, "Updating configuration to: " + values);
16060                }
16061
16062                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16063
16064                if (values.locale != null && !initLocale) {
16065                    saveLocaleLocked(values.locale,
16066                                     !values.locale.equals(mConfiguration.locale),
16067                                     values.userSetLocale);
16068                }
16069
16070                mConfigurationSeq++;
16071                if (mConfigurationSeq <= 0) {
16072                    mConfigurationSeq = 1;
16073                }
16074                newConfig.seq = mConfigurationSeq;
16075                mConfiguration = newConfig;
16076                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16077                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16078                //mUsageStatsService.noteStartConfig(newConfig);
16079
16080                final Configuration configCopy = new Configuration(mConfiguration);
16081
16082                // TODO: If our config changes, should we auto dismiss any currently
16083                // showing dialogs?
16084                mShowDialogs = shouldShowDialogs(newConfig);
16085
16086                AttributeCache ac = AttributeCache.instance();
16087                if (ac != null) {
16088                    ac.updateConfiguration(configCopy);
16089                }
16090
16091                // Make sure all resources in our process are updated
16092                // right now, so that anyone who is going to retrieve
16093                // resource values after we return will be sure to get
16094                // the new ones.  This is especially important during
16095                // boot, where the first config change needs to guarantee
16096                // all resources have that config before following boot
16097                // code is executed.
16098                mSystemThread.applyConfigurationToResources(configCopy);
16099
16100                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16101                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16102                    msg.obj = new Configuration(configCopy);
16103                    mHandler.sendMessage(msg);
16104                }
16105
16106                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16107                    ProcessRecord app = mLruProcesses.get(i);
16108                    try {
16109                        if (app.thread != null) {
16110                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16111                                    + app.processName + " new config " + mConfiguration);
16112                            app.thread.scheduleConfigurationChanged(configCopy);
16113                        }
16114                    } catch (Exception e) {
16115                    }
16116                }
16117                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16118                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16119                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16120                        | Intent.FLAG_RECEIVER_FOREGROUND);
16121                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16122                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16123                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16124                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16125                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16126                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16127                    broadcastIntentLocked(null, null, intent,
16128                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16129                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16130                }
16131            }
16132        }
16133
16134        boolean kept = true;
16135        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16136        // mainStack is null during startup.
16137        if (mainStack != null) {
16138            if (changes != 0 && starting == null) {
16139                // If the configuration changed, and the caller is not already
16140                // in the process of starting an activity, then find the top
16141                // activity to check if its configuration needs to change.
16142                starting = mainStack.topRunningActivityLocked(null);
16143            }
16144
16145            if (starting != null) {
16146                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16147                // And we need to make sure at this point that all other activities
16148                // are made visible with the correct configuration.
16149                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16150            }
16151        }
16152
16153        if (values != null && mWindowManager != null) {
16154            mWindowManager.setNewConfiguration(mConfiguration);
16155        }
16156
16157        return kept;
16158    }
16159
16160    /**
16161     * Decide based on the configuration whether we should shouw the ANR,
16162     * crash, etc dialogs.  The idea is that if there is no affordnace to
16163     * press the on-screen buttons, we shouldn't show the dialog.
16164     *
16165     * A thought: SystemUI might also want to get told about this, the Power
16166     * dialog / global actions also might want different behaviors.
16167     */
16168    private static final boolean shouldShowDialogs(Configuration config) {
16169        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16170                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16171    }
16172
16173    /**
16174     * Save the locale.  You must be inside a synchronized (this) block.
16175     */
16176    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16177        if(isDiff) {
16178            SystemProperties.set("user.language", l.getLanguage());
16179            SystemProperties.set("user.region", l.getCountry());
16180        }
16181
16182        if(isPersist) {
16183            SystemProperties.set("persist.sys.language", l.getLanguage());
16184            SystemProperties.set("persist.sys.country", l.getCountry());
16185            SystemProperties.set("persist.sys.localevar", l.getVariant());
16186        }
16187    }
16188
16189    @Override
16190    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16191        synchronized (this) {
16192            ActivityRecord srec = ActivityRecord.forToken(token);
16193            if (srec.task != null && srec.task.stack != null) {
16194                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16195            }
16196        }
16197        return false;
16198    }
16199
16200    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16201            Intent resultData) {
16202
16203        synchronized (this) {
16204            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16205            if (stack != null) {
16206                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16207            }
16208            return false;
16209        }
16210    }
16211
16212    public int getLaunchedFromUid(IBinder activityToken) {
16213        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16214        if (srec == null) {
16215            return -1;
16216        }
16217        return srec.launchedFromUid;
16218    }
16219
16220    public String getLaunchedFromPackage(IBinder activityToken) {
16221        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16222        if (srec == null) {
16223            return null;
16224        }
16225        return srec.launchedFromPackage;
16226    }
16227
16228    // =========================================================
16229    // LIFETIME MANAGEMENT
16230    // =========================================================
16231
16232    // Returns which broadcast queue the app is the current [or imminent] receiver
16233    // on, or 'null' if the app is not an active broadcast recipient.
16234    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16235        BroadcastRecord r = app.curReceiver;
16236        if (r != null) {
16237            return r.queue;
16238        }
16239
16240        // It's not the current receiver, but it might be starting up to become one
16241        synchronized (this) {
16242            for (BroadcastQueue queue : mBroadcastQueues) {
16243                r = queue.mPendingBroadcast;
16244                if (r != null && r.curApp == app) {
16245                    // found it; report which queue it's in
16246                    return queue;
16247                }
16248            }
16249        }
16250
16251        return null;
16252    }
16253
16254    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16255            boolean doingAll, long now) {
16256        if (mAdjSeq == app.adjSeq) {
16257            // This adjustment has already been computed.
16258            return app.curRawAdj;
16259        }
16260
16261        if (app.thread == null) {
16262            app.adjSeq = mAdjSeq;
16263            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16264            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16265            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16266        }
16267
16268        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16269        app.adjSource = null;
16270        app.adjTarget = null;
16271        app.empty = false;
16272        app.cached = false;
16273
16274        final int activitiesSize = app.activities.size();
16275
16276        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16277            // The max adjustment doesn't allow this app to be anything
16278            // below foreground, so it is not worth doing work for it.
16279            app.adjType = "fixed";
16280            app.adjSeq = mAdjSeq;
16281            app.curRawAdj = app.maxAdj;
16282            app.foregroundActivities = false;
16283            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16284            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16285            // System processes can do UI, and when they do we want to have
16286            // them trim their memory after the user leaves the UI.  To
16287            // facilitate this, here we need to determine whether or not it
16288            // is currently showing UI.
16289            app.systemNoUi = true;
16290            if (app == TOP_APP) {
16291                app.systemNoUi = false;
16292            } else if (activitiesSize > 0) {
16293                for (int j = 0; j < activitiesSize; j++) {
16294                    final ActivityRecord r = app.activities.get(j);
16295                    if (r.visible) {
16296                        app.systemNoUi = false;
16297                    }
16298                }
16299            }
16300            if (!app.systemNoUi) {
16301                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16302            }
16303            return (app.curAdj=app.maxAdj);
16304        }
16305
16306        app.systemNoUi = false;
16307
16308        // Determine the importance of the process, starting with most
16309        // important to least, and assign an appropriate OOM adjustment.
16310        int adj;
16311        int schedGroup;
16312        int procState;
16313        boolean foregroundActivities = false;
16314        BroadcastQueue queue;
16315        if (app == TOP_APP) {
16316            // The last app on the list is the foreground app.
16317            adj = ProcessList.FOREGROUND_APP_ADJ;
16318            schedGroup = Process.THREAD_GROUP_DEFAULT;
16319            app.adjType = "top-activity";
16320            foregroundActivities = true;
16321            procState = ActivityManager.PROCESS_STATE_TOP;
16322        } else if (app.instrumentationClass != null) {
16323            // Don't want to kill running instrumentation.
16324            adj = ProcessList.FOREGROUND_APP_ADJ;
16325            schedGroup = Process.THREAD_GROUP_DEFAULT;
16326            app.adjType = "instrumentation";
16327            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16328        } else if ((queue = isReceivingBroadcast(app)) != null) {
16329            // An app that is currently receiving a broadcast also
16330            // counts as being in the foreground for OOM killer purposes.
16331            // It's placed in a sched group based on the nature of the
16332            // broadcast as reflected by which queue it's active in.
16333            adj = ProcessList.FOREGROUND_APP_ADJ;
16334            schedGroup = (queue == mFgBroadcastQueue)
16335                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16336            app.adjType = "broadcast";
16337            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16338        } else if (app.executingServices.size() > 0) {
16339            // An app that is currently executing a service callback also
16340            // counts as being in the foreground.
16341            adj = ProcessList.FOREGROUND_APP_ADJ;
16342            schedGroup = app.execServicesFg ?
16343                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16344            app.adjType = "exec-service";
16345            procState = ActivityManager.PROCESS_STATE_SERVICE;
16346            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16347        } else {
16348            // As far as we know the process is empty.  We may change our mind later.
16349            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16350            // At this point we don't actually know the adjustment.  Use the cached adj
16351            // value that the caller wants us to.
16352            adj = cachedAdj;
16353            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16354            app.cached = true;
16355            app.empty = true;
16356            app.adjType = "cch-empty";
16357        }
16358
16359        // Examine all activities if not already foreground.
16360        if (!foregroundActivities && activitiesSize > 0) {
16361            for (int j = 0; j < activitiesSize; j++) {
16362                final ActivityRecord r = app.activities.get(j);
16363                if (r.app != app) {
16364                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16365                            + app + "?!?");
16366                    continue;
16367                }
16368                if (r.visible) {
16369                    // App has a visible activity; only upgrade adjustment.
16370                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16371                        adj = ProcessList.VISIBLE_APP_ADJ;
16372                        app.adjType = "visible";
16373                    }
16374                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16375                        procState = ActivityManager.PROCESS_STATE_TOP;
16376                    }
16377                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16378                    app.cached = false;
16379                    app.empty = false;
16380                    foregroundActivities = true;
16381                    break;
16382                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16383                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16384                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16385                        app.adjType = "pausing";
16386                    }
16387                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16388                        procState = ActivityManager.PROCESS_STATE_TOP;
16389                    }
16390                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16391                    app.cached = false;
16392                    app.empty = false;
16393                    foregroundActivities = true;
16394                } else if (r.state == ActivityState.STOPPING) {
16395                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16396                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16397                        app.adjType = "stopping";
16398                    }
16399                    // For the process state, we will at this point consider the
16400                    // process to be cached.  It will be cached either as an activity
16401                    // or empty depending on whether the activity is finishing.  We do
16402                    // this so that we can treat the process as cached for purposes of
16403                    // memory trimming (determing current memory level, trim command to
16404                    // send to process) since there can be an arbitrary number of stopping
16405                    // processes and they should soon all go into the cached state.
16406                    if (!r.finishing) {
16407                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16408                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16409                        }
16410                    }
16411                    app.cached = false;
16412                    app.empty = false;
16413                    foregroundActivities = true;
16414                } else {
16415                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16416                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16417                        app.adjType = "cch-act";
16418                    }
16419                }
16420            }
16421        }
16422
16423        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16424            if (app.foregroundServices) {
16425                // The user is aware of this app, so make it visible.
16426                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16427                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16428                app.cached = false;
16429                app.adjType = "fg-service";
16430                schedGroup = Process.THREAD_GROUP_DEFAULT;
16431            } else if (app.forcingToForeground != null) {
16432                // The user is aware of this app, so make it visible.
16433                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16434                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16435                app.cached = false;
16436                app.adjType = "force-fg";
16437                app.adjSource = app.forcingToForeground;
16438                schedGroup = Process.THREAD_GROUP_DEFAULT;
16439            }
16440        }
16441
16442        if (app == mHeavyWeightProcess) {
16443            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16444                // We don't want to kill the current heavy-weight process.
16445                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16446                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16447                app.cached = false;
16448                app.adjType = "heavy";
16449            }
16450            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16451                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16452            }
16453        }
16454
16455        if (app == mHomeProcess) {
16456            if (adj > ProcessList.HOME_APP_ADJ) {
16457                // This process is hosting what we currently consider to be the
16458                // home app, so we don't want to let it go into the background.
16459                adj = ProcessList.HOME_APP_ADJ;
16460                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16461                app.cached = false;
16462                app.adjType = "home";
16463            }
16464            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16465                procState = ActivityManager.PROCESS_STATE_HOME;
16466            }
16467        }
16468
16469        if (app == mPreviousProcess && app.activities.size() > 0) {
16470            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16471                // This was the previous process that showed UI to the user.
16472                // We want to try to keep it around more aggressively, to give
16473                // a good experience around switching between two apps.
16474                adj = ProcessList.PREVIOUS_APP_ADJ;
16475                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16476                app.cached = false;
16477                app.adjType = "previous";
16478            }
16479            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16480                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16481            }
16482        }
16483
16484        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16485                + " reason=" + app.adjType);
16486
16487        // By default, we use the computed adjustment.  It may be changed if
16488        // there are applications dependent on our services or providers, but
16489        // this gives us a baseline and makes sure we don't get into an
16490        // infinite recursion.
16491        app.adjSeq = mAdjSeq;
16492        app.curRawAdj = adj;
16493        app.hasStartedServices = false;
16494
16495        if (mBackupTarget != null && app == mBackupTarget.app) {
16496            // If possible we want to avoid killing apps while they're being backed up
16497            if (adj > ProcessList.BACKUP_APP_ADJ) {
16498                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16499                adj = ProcessList.BACKUP_APP_ADJ;
16500                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16501                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16502                }
16503                app.adjType = "backup";
16504                app.cached = false;
16505            }
16506            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16507                procState = ActivityManager.PROCESS_STATE_BACKUP;
16508            }
16509        }
16510
16511        boolean mayBeTop = false;
16512
16513        for (int is = app.services.size()-1;
16514                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16515                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16516                        || procState > ActivityManager.PROCESS_STATE_TOP);
16517                is--) {
16518            ServiceRecord s = app.services.valueAt(is);
16519            if (s.startRequested) {
16520                app.hasStartedServices = true;
16521                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16522                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16523                }
16524                if (app.hasShownUi && app != mHomeProcess) {
16525                    // If this process has shown some UI, let it immediately
16526                    // go to the LRU list because it may be pretty heavy with
16527                    // UI stuff.  We'll tag it with a label just to help
16528                    // debug and understand what is going on.
16529                    if (adj > ProcessList.SERVICE_ADJ) {
16530                        app.adjType = "cch-started-ui-services";
16531                    }
16532                } else {
16533                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16534                        // This service has seen some activity within
16535                        // recent memory, so we will keep its process ahead
16536                        // of the background processes.
16537                        if (adj > ProcessList.SERVICE_ADJ) {
16538                            adj = ProcessList.SERVICE_ADJ;
16539                            app.adjType = "started-services";
16540                            app.cached = false;
16541                        }
16542                    }
16543                    // If we have let the service slide into the background
16544                    // state, still have some text describing what it is doing
16545                    // even though the service no longer has an impact.
16546                    if (adj > ProcessList.SERVICE_ADJ) {
16547                        app.adjType = "cch-started-services";
16548                    }
16549                }
16550            }
16551            for (int conni = s.connections.size()-1;
16552                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16553                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16554                            || procState > ActivityManager.PROCESS_STATE_TOP);
16555                    conni--) {
16556                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16557                for (int i = 0;
16558                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16559                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16560                                || procState > ActivityManager.PROCESS_STATE_TOP);
16561                        i++) {
16562                    // XXX should compute this based on the max of
16563                    // all connected clients.
16564                    ConnectionRecord cr = clist.get(i);
16565                    if (cr.binding.client == app) {
16566                        // Binding to ourself is not interesting.
16567                        continue;
16568                    }
16569                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16570                        ProcessRecord client = cr.binding.client;
16571                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16572                                TOP_APP, doingAll, now);
16573                        int clientProcState = client.curProcState;
16574                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16575                            // If the other app is cached for any reason, for purposes here
16576                            // we are going to consider it empty.  The specific cached state
16577                            // doesn't propagate except under certain conditions.
16578                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16579                        }
16580                        String adjType = null;
16581                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16582                            // Not doing bind OOM management, so treat
16583                            // this guy more like a started service.
16584                            if (app.hasShownUi && app != mHomeProcess) {
16585                                // If this process has shown some UI, let it immediately
16586                                // go to the LRU list because it may be pretty heavy with
16587                                // UI stuff.  We'll tag it with a label just to help
16588                                // debug and understand what is going on.
16589                                if (adj > clientAdj) {
16590                                    adjType = "cch-bound-ui-services";
16591                                }
16592                                app.cached = false;
16593                                clientAdj = adj;
16594                                clientProcState = procState;
16595                            } else {
16596                                if (now >= (s.lastActivity
16597                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16598                                    // This service has not seen activity within
16599                                    // recent memory, so allow it to drop to the
16600                                    // LRU list if there is no other reason to keep
16601                                    // it around.  We'll also tag it with a label just
16602                                    // to help debug and undertand what is going on.
16603                                    if (adj > clientAdj) {
16604                                        adjType = "cch-bound-services";
16605                                    }
16606                                    clientAdj = adj;
16607                                }
16608                            }
16609                        }
16610                        if (adj > clientAdj) {
16611                            // If this process has recently shown UI, and
16612                            // the process that is binding to it is less
16613                            // important than being visible, then we don't
16614                            // care about the binding as much as we care
16615                            // about letting this process get into the LRU
16616                            // list to be killed and restarted if needed for
16617                            // memory.
16618                            if (app.hasShownUi && app != mHomeProcess
16619                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16620                                adjType = "cch-bound-ui-services";
16621                            } else {
16622                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16623                                        |Context.BIND_IMPORTANT)) != 0) {
16624                                    adj = clientAdj;
16625                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16626                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16627                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16628                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16629                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16630                                    adj = clientAdj;
16631                                } else {
16632                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16633                                        adj = ProcessList.VISIBLE_APP_ADJ;
16634                                    }
16635                                }
16636                                if (!client.cached) {
16637                                    app.cached = false;
16638                                }
16639                                adjType = "service";
16640                            }
16641                        }
16642                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16643                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16644                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16645                            }
16646                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16647                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16648                                    // Special handling of clients who are in the top state.
16649                                    // We *may* want to consider this process to be in the
16650                                    // top state as well, but only if there is not another
16651                                    // reason for it to be running.  Being on the top is a
16652                                    // special state, meaning you are specifically running
16653                                    // for the current top app.  If the process is already
16654                                    // running in the background for some other reason, it
16655                                    // is more important to continue considering it to be
16656                                    // in the background state.
16657                                    mayBeTop = true;
16658                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16659                                } else {
16660                                    // Special handling for above-top states (persistent
16661                                    // processes).  These should not bring the current process
16662                                    // into the top state, since they are not on top.  Instead
16663                                    // give them the best state after that.
16664                                    clientProcState =
16665                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16666                                }
16667                            }
16668                        } else {
16669                            if (clientProcState <
16670                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16671                                clientProcState =
16672                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16673                            }
16674                        }
16675                        if (procState > clientProcState) {
16676                            procState = clientProcState;
16677                        }
16678                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16679                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16680                            app.pendingUiClean = true;
16681                        }
16682                        if (adjType != null) {
16683                            app.adjType = adjType;
16684                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16685                                    .REASON_SERVICE_IN_USE;
16686                            app.adjSource = cr.binding.client;
16687                            app.adjSourceProcState = clientProcState;
16688                            app.adjTarget = s.name;
16689                        }
16690                    }
16691                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16692                        app.treatLikeActivity = true;
16693                    }
16694                    final ActivityRecord a = cr.activity;
16695                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16696                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16697                                (a.visible || a.state == ActivityState.RESUMED
16698                                 || a.state == ActivityState.PAUSING)) {
16699                            adj = ProcessList.FOREGROUND_APP_ADJ;
16700                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16701                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16702                            }
16703                            app.cached = false;
16704                            app.adjType = "service";
16705                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16706                                    .REASON_SERVICE_IN_USE;
16707                            app.adjSource = a;
16708                            app.adjSourceProcState = procState;
16709                            app.adjTarget = s.name;
16710                        }
16711                    }
16712                }
16713            }
16714        }
16715
16716        for (int provi = app.pubProviders.size()-1;
16717                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16718                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16719                        || procState > ActivityManager.PROCESS_STATE_TOP);
16720                provi--) {
16721            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16722            for (int i = cpr.connections.size()-1;
16723                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16724                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16725                            || procState > ActivityManager.PROCESS_STATE_TOP);
16726                    i--) {
16727                ContentProviderConnection conn = cpr.connections.get(i);
16728                ProcessRecord client = conn.client;
16729                if (client == app) {
16730                    // Being our own client is not interesting.
16731                    continue;
16732                }
16733                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16734                int clientProcState = client.curProcState;
16735                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16736                    // If the other app is cached for any reason, for purposes here
16737                    // we are going to consider it empty.
16738                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16739                }
16740                if (adj > clientAdj) {
16741                    if (app.hasShownUi && app != mHomeProcess
16742                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16743                        app.adjType = "cch-ui-provider";
16744                    } else {
16745                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16746                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16747                        app.adjType = "provider";
16748                    }
16749                    app.cached &= client.cached;
16750                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16751                            .REASON_PROVIDER_IN_USE;
16752                    app.adjSource = client;
16753                    app.adjSourceProcState = clientProcState;
16754                    app.adjTarget = cpr.name;
16755                }
16756                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16757                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16758                        // Special handling of clients who are in the top state.
16759                        // We *may* want to consider this process to be in the
16760                        // top state as well, but only if there is not another
16761                        // reason for it to be running.  Being on the top is a
16762                        // special state, meaning you are specifically running
16763                        // for the current top app.  If the process is already
16764                        // running in the background for some other reason, it
16765                        // is more important to continue considering it to be
16766                        // in the background state.
16767                        mayBeTop = true;
16768                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16769                    } else {
16770                        // Special handling for above-top states (persistent
16771                        // processes).  These should not bring the current process
16772                        // into the top state, since they are not on top.  Instead
16773                        // give them the best state after that.
16774                        clientProcState =
16775                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16776                    }
16777                }
16778                if (procState > clientProcState) {
16779                    procState = clientProcState;
16780                }
16781                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16782                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16783                }
16784            }
16785            // If the provider has external (non-framework) process
16786            // dependencies, ensure that its adjustment is at least
16787            // FOREGROUND_APP_ADJ.
16788            if (cpr.hasExternalProcessHandles()) {
16789                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16790                    adj = ProcessList.FOREGROUND_APP_ADJ;
16791                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16792                    app.cached = false;
16793                    app.adjType = "provider";
16794                    app.adjTarget = cpr.name;
16795                }
16796                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16797                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16798                }
16799            }
16800        }
16801
16802        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16803            // A client of one of our services or providers is in the top state.  We
16804            // *may* want to be in the top state, but not if we are already running in
16805            // the background for some other reason.  For the decision here, we are going
16806            // to pick out a few specific states that we want to remain in when a client
16807            // is top (states that tend to be longer-term) and otherwise allow it to go
16808            // to the top state.
16809            switch (procState) {
16810                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16811                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16812                case ActivityManager.PROCESS_STATE_SERVICE:
16813                    // These all are longer-term states, so pull them up to the top
16814                    // of the background states, but not all the way to the top state.
16815                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16816                    break;
16817                default:
16818                    // Otherwise, top is a better choice, so take it.
16819                    procState = ActivityManager.PROCESS_STATE_TOP;
16820                    break;
16821            }
16822        }
16823
16824        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16825            if (app.hasClientActivities) {
16826                // This is a cached process, but with client activities.  Mark it so.
16827                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16828                app.adjType = "cch-client-act";
16829            } else if (app.treatLikeActivity) {
16830                // This is a cached process, but somebody wants us to treat it like it has
16831                // an activity, okay!
16832                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16833                app.adjType = "cch-as-act";
16834            }
16835        }
16836
16837        if (adj == ProcessList.SERVICE_ADJ) {
16838            if (doingAll) {
16839                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16840                mNewNumServiceProcs++;
16841                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16842                if (!app.serviceb) {
16843                    // This service isn't far enough down on the LRU list to
16844                    // normally be a B service, but if we are low on RAM and it
16845                    // is large we want to force it down since we would prefer to
16846                    // keep launcher over it.
16847                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16848                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16849                        app.serviceHighRam = true;
16850                        app.serviceb = true;
16851                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16852                    } else {
16853                        mNewNumAServiceProcs++;
16854                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16855                    }
16856                } else {
16857                    app.serviceHighRam = false;
16858                }
16859            }
16860            if (app.serviceb) {
16861                adj = ProcessList.SERVICE_B_ADJ;
16862            }
16863        }
16864
16865        app.curRawAdj = adj;
16866
16867        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16868        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16869        if (adj > app.maxAdj) {
16870            adj = app.maxAdj;
16871            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16872                schedGroup = Process.THREAD_GROUP_DEFAULT;
16873            }
16874        }
16875
16876        // Do final modification to adj.  Everything we do between here and applying
16877        // the final setAdj must be done in this function, because we will also use
16878        // it when computing the final cached adj later.  Note that we don't need to
16879        // worry about this for max adj above, since max adj will always be used to
16880        // keep it out of the cached vaues.
16881        app.curAdj = app.modifyRawOomAdj(adj);
16882        app.curSchedGroup = schedGroup;
16883        app.curProcState = procState;
16884        app.foregroundActivities = foregroundActivities;
16885
16886        return app.curRawAdj;
16887    }
16888
16889    /**
16890     * Schedule PSS collection of a process.
16891     */
16892    void requestPssLocked(ProcessRecord proc, int procState) {
16893        if (mPendingPssProcesses.contains(proc)) {
16894            return;
16895        }
16896        if (mPendingPssProcesses.size() == 0) {
16897            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16898        }
16899        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16900        proc.pssProcState = procState;
16901        mPendingPssProcesses.add(proc);
16902    }
16903
16904    /**
16905     * Schedule PSS collection of all processes.
16906     */
16907    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16908        if (!always) {
16909            if (now < (mLastFullPssTime +
16910                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16911                return;
16912            }
16913        }
16914        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16915        mLastFullPssTime = now;
16916        mFullPssPending = true;
16917        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16918        mPendingPssProcesses.clear();
16919        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16920            ProcessRecord app = mLruProcesses.get(i);
16921            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16922                app.pssProcState = app.setProcState;
16923                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16924                        isSleeping(), now);
16925                mPendingPssProcesses.add(app);
16926            }
16927        }
16928        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16929    }
16930
16931    /**
16932     * Ask a given process to GC right now.
16933     */
16934    final void performAppGcLocked(ProcessRecord app) {
16935        try {
16936            app.lastRequestedGc = SystemClock.uptimeMillis();
16937            if (app.thread != null) {
16938                if (app.reportLowMemory) {
16939                    app.reportLowMemory = false;
16940                    app.thread.scheduleLowMemory();
16941                } else {
16942                    app.thread.processInBackground();
16943                }
16944            }
16945        } catch (Exception e) {
16946            // whatever.
16947        }
16948    }
16949
16950    /**
16951     * Returns true if things are idle enough to perform GCs.
16952     */
16953    private final boolean canGcNowLocked() {
16954        boolean processingBroadcasts = false;
16955        for (BroadcastQueue q : mBroadcastQueues) {
16956            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16957                processingBroadcasts = true;
16958            }
16959        }
16960        return !processingBroadcasts
16961                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16962    }
16963
16964    /**
16965     * Perform GCs on all processes that are waiting for it, but only
16966     * if things are idle.
16967     */
16968    final void performAppGcsLocked() {
16969        final int N = mProcessesToGc.size();
16970        if (N <= 0) {
16971            return;
16972        }
16973        if (canGcNowLocked()) {
16974            while (mProcessesToGc.size() > 0) {
16975                ProcessRecord proc = mProcessesToGc.remove(0);
16976                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16977                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16978                            <= SystemClock.uptimeMillis()) {
16979                        // To avoid spamming the system, we will GC processes one
16980                        // at a time, waiting a few seconds between each.
16981                        performAppGcLocked(proc);
16982                        scheduleAppGcsLocked();
16983                        return;
16984                    } else {
16985                        // It hasn't been long enough since we last GCed this
16986                        // process...  put it in the list to wait for its time.
16987                        addProcessToGcListLocked(proc);
16988                        break;
16989                    }
16990                }
16991            }
16992
16993            scheduleAppGcsLocked();
16994        }
16995    }
16996
16997    /**
16998     * If all looks good, perform GCs on all processes waiting for them.
16999     */
17000    final void performAppGcsIfAppropriateLocked() {
17001        if (canGcNowLocked()) {
17002            performAppGcsLocked();
17003            return;
17004        }
17005        // Still not idle, wait some more.
17006        scheduleAppGcsLocked();
17007    }
17008
17009    /**
17010     * Schedule the execution of all pending app GCs.
17011     */
17012    final void scheduleAppGcsLocked() {
17013        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17014
17015        if (mProcessesToGc.size() > 0) {
17016            // Schedule a GC for the time to the next process.
17017            ProcessRecord proc = mProcessesToGc.get(0);
17018            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17019
17020            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17021            long now = SystemClock.uptimeMillis();
17022            if (when < (now+GC_TIMEOUT)) {
17023                when = now + GC_TIMEOUT;
17024            }
17025            mHandler.sendMessageAtTime(msg, when);
17026        }
17027    }
17028
17029    /**
17030     * Add a process to the array of processes waiting to be GCed.  Keeps the
17031     * list in sorted order by the last GC time.  The process can't already be
17032     * on the list.
17033     */
17034    final void addProcessToGcListLocked(ProcessRecord proc) {
17035        boolean added = false;
17036        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17037            if (mProcessesToGc.get(i).lastRequestedGc <
17038                    proc.lastRequestedGc) {
17039                added = true;
17040                mProcessesToGc.add(i+1, proc);
17041                break;
17042            }
17043        }
17044        if (!added) {
17045            mProcessesToGc.add(0, proc);
17046        }
17047    }
17048
17049    /**
17050     * Set up to ask a process to GC itself.  This will either do it
17051     * immediately, or put it on the list of processes to gc the next
17052     * time things are idle.
17053     */
17054    final void scheduleAppGcLocked(ProcessRecord app) {
17055        long now = SystemClock.uptimeMillis();
17056        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17057            return;
17058        }
17059        if (!mProcessesToGc.contains(app)) {
17060            addProcessToGcListLocked(app);
17061            scheduleAppGcsLocked();
17062        }
17063    }
17064
17065    final void checkExcessivePowerUsageLocked(boolean doKills) {
17066        updateCpuStatsNow();
17067
17068        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17069        boolean doWakeKills = doKills;
17070        boolean doCpuKills = doKills;
17071        if (mLastPowerCheckRealtime == 0) {
17072            doWakeKills = false;
17073        }
17074        if (mLastPowerCheckUptime == 0) {
17075            doCpuKills = false;
17076        }
17077        if (stats.isScreenOn()) {
17078            doWakeKills = false;
17079        }
17080        final long curRealtime = SystemClock.elapsedRealtime();
17081        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17082        final long curUptime = SystemClock.uptimeMillis();
17083        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17084        mLastPowerCheckRealtime = curRealtime;
17085        mLastPowerCheckUptime = curUptime;
17086        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17087            doWakeKills = false;
17088        }
17089        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17090            doCpuKills = false;
17091        }
17092        int i = mLruProcesses.size();
17093        while (i > 0) {
17094            i--;
17095            ProcessRecord app = mLruProcesses.get(i);
17096            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17097                long wtime;
17098                synchronized (stats) {
17099                    wtime = stats.getProcessWakeTime(app.info.uid,
17100                            app.pid, curRealtime);
17101                }
17102                long wtimeUsed = wtime - app.lastWakeTime;
17103                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17104                if (DEBUG_POWER) {
17105                    StringBuilder sb = new StringBuilder(128);
17106                    sb.append("Wake for ");
17107                    app.toShortString(sb);
17108                    sb.append(": over ");
17109                    TimeUtils.formatDuration(realtimeSince, sb);
17110                    sb.append(" used ");
17111                    TimeUtils.formatDuration(wtimeUsed, sb);
17112                    sb.append(" (");
17113                    sb.append((wtimeUsed*100)/realtimeSince);
17114                    sb.append("%)");
17115                    Slog.i(TAG, sb.toString());
17116                    sb.setLength(0);
17117                    sb.append("CPU for ");
17118                    app.toShortString(sb);
17119                    sb.append(": over ");
17120                    TimeUtils.formatDuration(uptimeSince, sb);
17121                    sb.append(" used ");
17122                    TimeUtils.formatDuration(cputimeUsed, sb);
17123                    sb.append(" (");
17124                    sb.append((cputimeUsed*100)/uptimeSince);
17125                    sb.append("%)");
17126                    Slog.i(TAG, sb.toString());
17127                }
17128                // If a process has held a wake lock for more
17129                // than 50% of the time during this period,
17130                // that sounds bad.  Kill!
17131                if (doWakeKills && realtimeSince > 0
17132                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17133                    synchronized (stats) {
17134                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17135                                realtimeSince, wtimeUsed);
17136                    }
17137                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17138                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17139                } else if (doCpuKills && uptimeSince > 0
17140                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17141                    synchronized (stats) {
17142                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17143                                uptimeSince, cputimeUsed);
17144                    }
17145                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17146                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17147                } else {
17148                    app.lastWakeTime = wtime;
17149                    app.lastCpuTime = app.curCpuTime;
17150                }
17151            }
17152        }
17153    }
17154
17155    private final boolean applyOomAdjLocked(ProcessRecord app,
17156            ProcessRecord TOP_APP, boolean doingAll, long now) {
17157        boolean success = true;
17158
17159        if (app.curRawAdj != app.setRawAdj) {
17160            app.setRawAdj = app.curRawAdj;
17161        }
17162
17163        int changes = 0;
17164
17165        if (app.curAdj != app.setAdj) {
17166            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17167            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17168                TAG, "Set " + app.pid + " " + app.processName +
17169                " adj " + app.curAdj + ": " + app.adjType);
17170            app.setAdj = app.curAdj;
17171        }
17172
17173        if (app.setSchedGroup != app.curSchedGroup) {
17174            app.setSchedGroup = app.curSchedGroup;
17175            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17176                    "Setting process group of " + app.processName
17177                    + " to " + app.curSchedGroup);
17178            if (app.waitingToKill != null &&
17179                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17180                app.kill(app.waitingToKill, true);
17181                success = false;
17182            } else {
17183                if (true) {
17184                    long oldId = Binder.clearCallingIdentity();
17185                    try {
17186                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17187                    } catch (Exception e) {
17188                        Slog.w(TAG, "Failed setting process group of " + app.pid
17189                                + " to " + app.curSchedGroup);
17190                        e.printStackTrace();
17191                    } finally {
17192                        Binder.restoreCallingIdentity(oldId);
17193                    }
17194                } else {
17195                    if (app.thread != null) {
17196                        try {
17197                            app.thread.setSchedulingGroup(app.curSchedGroup);
17198                        } catch (RemoteException e) {
17199                        }
17200                    }
17201                }
17202                Process.setSwappiness(app.pid,
17203                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17204            }
17205        }
17206        if (app.repForegroundActivities != app.foregroundActivities) {
17207            app.repForegroundActivities = app.foregroundActivities;
17208            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17209        }
17210        if (app.repProcState != app.curProcState) {
17211            app.repProcState = app.curProcState;
17212            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17213            if (app.thread != null) {
17214                try {
17215                    if (false) {
17216                        //RuntimeException h = new RuntimeException("here");
17217                        Slog.i(TAG, "Sending new process state " + app.repProcState
17218                                + " to " + app /*, h*/);
17219                    }
17220                    app.thread.setProcessState(app.repProcState);
17221                } catch (RemoteException e) {
17222                }
17223            }
17224        }
17225        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17226                app.setProcState)) {
17227            app.lastStateTime = now;
17228            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17229                    isSleeping(), now);
17230            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17231                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17232                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17233                    + (app.nextPssTime-now) + ": " + app);
17234        } else {
17235            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17236                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17237                requestPssLocked(app, app.setProcState);
17238                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17239                        isSleeping(), now);
17240            } else if (false && DEBUG_PSS) {
17241                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17242            }
17243        }
17244        if (app.setProcState != app.curProcState) {
17245            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17246                    "Proc state change of " + app.processName
17247                    + " to " + app.curProcState);
17248            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17249            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17250            if (setImportant && !curImportant) {
17251                // This app is no longer something we consider important enough to allow to
17252                // use arbitrary amounts of battery power.  Note
17253                // its current wake lock time to later know to kill it if
17254                // it is not behaving well.
17255                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17256                synchronized (stats) {
17257                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17258                            app.pid, SystemClock.elapsedRealtime());
17259                }
17260                app.lastCpuTime = app.curCpuTime;
17261
17262            }
17263            app.setProcState = app.curProcState;
17264            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17265                app.notCachedSinceIdle = false;
17266            }
17267            if (!doingAll) {
17268                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17269            } else {
17270                app.procStateChanged = true;
17271            }
17272        }
17273
17274        if (changes != 0) {
17275            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17276            int i = mPendingProcessChanges.size()-1;
17277            ProcessChangeItem item = null;
17278            while (i >= 0) {
17279                item = mPendingProcessChanges.get(i);
17280                if (item.pid == app.pid) {
17281                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17282                    break;
17283                }
17284                i--;
17285            }
17286            if (i < 0) {
17287                // No existing item in pending changes; need a new one.
17288                final int NA = mAvailProcessChanges.size();
17289                if (NA > 0) {
17290                    item = mAvailProcessChanges.remove(NA-1);
17291                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17292                } else {
17293                    item = new ProcessChangeItem();
17294                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17295                }
17296                item.changes = 0;
17297                item.pid = app.pid;
17298                item.uid = app.info.uid;
17299                if (mPendingProcessChanges.size() == 0) {
17300                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17301                            "*** Enqueueing dispatch processes changed!");
17302                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17303                }
17304                mPendingProcessChanges.add(item);
17305            }
17306            item.changes |= changes;
17307            item.processState = app.repProcState;
17308            item.foregroundActivities = app.repForegroundActivities;
17309            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17310                    + Integer.toHexString(System.identityHashCode(item))
17311                    + " " + app.toShortString() + ": changes=" + item.changes
17312                    + " procState=" + item.processState
17313                    + " foreground=" + item.foregroundActivities
17314                    + " type=" + app.adjType + " source=" + app.adjSource
17315                    + " target=" + app.adjTarget);
17316        }
17317
17318        return success;
17319    }
17320
17321    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17322        if (proc.thread != null) {
17323            if (proc.baseProcessTracker != null) {
17324                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17325            }
17326            if (proc.repProcState >= 0) {
17327                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17328                        proc.repProcState);
17329            }
17330        }
17331    }
17332
17333    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17334            ProcessRecord TOP_APP, boolean doingAll, long now) {
17335        if (app.thread == null) {
17336            return false;
17337        }
17338
17339        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17340
17341        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17342    }
17343
17344    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17345            boolean oomAdj) {
17346        if (isForeground != proc.foregroundServices) {
17347            proc.foregroundServices = isForeground;
17348            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17349                    proc.info.uid);
17350            if (isForeground) {
17351                if (curProcs == null) {
17352                    curProcs = new ArrayList<ProcessRecord>();
17353                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17354                }
17355                if (!curProcs.contains(proc)) {
17356                    curProcs.add(proc);
17357                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17358                            proc.info.packageName, proc.info.uid);
17359                }
17360            } else {
17361                if (curProcs != null) {
17362                    if (curProcs.remove(proc)) {
17363                        mBatteryStatsService.noteEvent(
17364                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17365                                proc.info.packageName, proc.info.uid);
17366                        if (curProcs.size() <= 0) {
17367                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17368                        }
17369                    }
17370                }
17371            }
17372            if (oomAdj) {
17373                updateOomAdjLocked();
17374            }
17375        }
17376    }
17377
17378    private final ActivityRecord resumedAppLocked() {
17379        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17380        String pkg;
17381        int uid;
17382        if (act != null) {
17383            pkg = act.packageName;
17384            uid = act.info.applicationInfo.uid;
17385        } else {
17386            pkg = null;
17387            uid = -1;
17388        }
17389        // Has the UID or resumed package name changed?
17390        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17391                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17392            if (mCurResumedPackage != null) {
17393                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17394                        mCurResumedPackage, mCurResumedUid);
17395            }
17396            mCurResumedPackage = pkg;
17397            mCurResumedUid = uid;
17398            if (mCurResumedPackage != null) {
17399                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17400                        mCurResumedPackage, mCurResumedUid);
17401            }
17402        }
17403        return act;
17404    }
17405
17406    final boolean updateOomAdjLocked(ProcessRecord app) {
17407        final ActivityRecord TOP_ACT = resumedAppLocked();
17408        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17409        final boolean wasCached = app.cached;
17410
17411        mAdjSeq++;
17412
17413        // This is the desired cached adjusment we want to tell it to use.
17414        // If our app is currently cached, we know it, and that is it.  Otherwise,
17415        // we don't know it yet, and it needs to now be cached we will then
17416        // need to do a complete oom adj.
17417        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17418                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17419        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17420                SystemClock.uptimeMillis());
17421        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17422            // Changed to/from cached state, so apps after it in the LRU
17423            // list may also be changed.
17424            updateOomAdjLocked();
17425        }
17426        return success;
17427    }
17428
17429    final void updateOomAdjLocked() {
17430        final ActivityRecord TOP_ACT = resumedAppLocked();
17431        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17432        final long now = SystemClock.uptimeMillis();
17433        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17434        final int N = mLruProcesses.size();
17435
17436        if (false) {
17437            RuntimeException e = new RuntimeException();
17438            e.fillInStackTrace();
17439            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17440        }
17441
17442        mAdjSeq++;
17443        mNewNumServiceProcs = 0;
17444        mNewNumAServiceProcs = 0;
17445
17446        final int emptyProcessLimit;
17447        final int cachedProcessLimit;
17448        if (mProcessLimit <= 0) {
17449            emptyProcessLimit = cachedProcessLimit = 0;
17450        } else if (mProcessLimit == 1) {
17451            emptyProcessLimit = 1;
17452            cachedProcessLimit = 0;
17453        } else {
17454            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17455            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17456        }
17457
17458        // Let's determine how many processes we have running vs.
17459        // how many slots we have for background processes; we may want
17460        // to put multiple processes in a slot of there are enough of
17461        // them.
17462        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17463                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17464        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17465        if (numEmptyProcs > cachedProcessLimit) {
17466            // If there are more empty processes than our limit on cached
17467            // processes, then use the cached process limit for the factor.
17468            // This ensures that the really old empty processes get pushed
17469            // down to the bottom, so if we are running low on memory we will
17470            // have a better chance at keeping around more cached processes
17471            // instead of a gazillion empty processes.
17472            numEmptyProcs = cachedProcessLimit;
17473        }
17474        int emptyFactor = numEmptyProcs/numSlots;
17475        if (emptyFactor < 1) emptyFactor = 1;
17476        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17477        if (cachedFactor < 1) cachedFactor = 1;
17478        int stepCached = 0;
17479        int stepEmpty = 0;
17480        int numCached = 0;
17481        int numEmpty = 0;
17482        int numTrimming = 0;
17483
17484        mNumNonCachedProcs = 0;
17485        mNumCachedHiddenProcs = 0;
17486
17487        // First update the OOM adjustment for each of the
17488        // application processes based on their current state.
17489        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17490        int nextCachedAdj = curCachedAdj+1;
17491        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17492        int nextEmptyAdj = curEmptyAdj+2;
17493        for (int i=N-1; i>=0; i--) {
17494            ProcessRecord app = mLruProcesses.get(i);
17495            if (!app.killedByAm && app.thread != null) {
17496                app.procStateChanged = false;
17497                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17498
17499                // If we haven't yet assigned the final cached adj
17500                // to the process, do that now.
17501                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17502                    switch (app.curProcState) {
17503                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17504                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17505                            // This process is a cached process holding activities...
17506                            // assign it the next cached value for that type, and then
17507                            // step that cached level.
17508                            app.curRawAdj = curCachedAdj;
17509                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17510                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17511                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17512                                    + ")");
17513                            if (curCachedAdj != nextCachedAdj) {
17514                                stepCached++;
17515                                if (stepCached >= cachedFactor) {
17516                                    stepCached = 0;
17517                                    curCachedAdj = nextCachedAdj;
17518                                    nextCachedAdj += 2;
17519                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17520                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17521                                    }
17522                                }
17523                            }
17524                            break;
17525                        default:
17526                            // For everything else, assign next empty cached process
17527                            // level and bump that up.  Note that this means that
17528                            // long-running services that have dropped down to the
17529                            // cached level will be treated as empty (since their process
17530                            // state is still as a service), which is what we want.
17531                            app.curRawAdj = curEmptyAdj;
17532                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17533                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17534                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17535                                    + ")");
17536                            if (curEmptyAdj != nextEmptyAdj) {
17537                                stepEmpty++;
17538                                if (stepEmpty >= emptyFactor) {
17539                                    stepEmpty = 0;
17540                                    curEmptyAdj = nextEmptyAdj;
17541                                    nextEmptyAdj += 2;
17542                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17543                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17544                                    }
17545                                }
17546                            }
17547                            break;
17548                    }
17549                }
17550
17551                applyOomAdjLocked(app, TOP_APP, true, now);
17552
17553                // Count the number of process types.
17554                switch (app.curProcState) {
17555                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17556                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17557                        mNumCachedHiddenProcs++;
17558                        numCached++;
17559                        if (numCached > cachedProcessLimit) {
17560                            app.kill("cached #" + numCached, true);
17561                        }
17562                        break;
17563                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17564                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17565                                && app.lastActivityTime < oldTime) {
17566                            app.kill("empty for "
17567                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17568                                    / 1000) + "s", true);
17569                        } else {
17570                            numEmpty++;
17571                            if (numEmpty > emptyProcessLimit) {
17572                                app.kill("empty #" + numEmpty, true);
17573                            }
17574                        }
17575                        break;
17576                    default:
17577                        mNumNonCachedProcs++;
17578                        break;
17579                }
17580
17581                if (app.isolated && app.services.size() <= 0) {
17582                    // If this is an isolated process, and there are no
17583                    // services running in it, then the process is no longer
17584                    // needed.  We agressively kill these because we can by
17585                    // definition not re-use the same process again, and it is
17586                    // good to avoid having whatever code was running in them
17587                    // left sitting around after no longer needed.
17588                    app.kill("isolated not needed", true);
17589                }
17590
17591                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17592                        && !app.killedByAm) {
17593                    numTrimming++;
17594                }
17595            }
17596        }
17597
17598        mNumServiceProcs = mNewNumServiceProcs;
17599
17600        // Now determine the memory trimming level of background processes.
17601        // Unfortunately we need to start at the back of the list to do this
17602        // properly.  We only do this if the number of background apps we
17603        // are managing to keep around is less than half the maximum we desire;
17604        // if we are keeping a good number around, we'll let them use whatever
17605        // memory they want.
17606        final int numCachedAndEmpty = numCached + numEmpty;
17607        int memFactor;
17608        if (numCached <= ProcessList.TRIM_CACHED_APPS
17609                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17610            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17611                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17612            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17613                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17614            } else {
17615                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17616            }
17617        } else {
17618            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17619        }
17620        // We always allow the memory level to go up (better).  We only allow it to go
17621        // down if we are in a state where that is allowed, *and* the total number of processes
17622        // has gone down since last time.
17623        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17624                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17625                + " last=" + mLastNumProcesses);
17626        if (memFactor > mLastMemoryLevel) {
17627            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17628                memFactor = mLastMemoryLevel;
17629                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17630            }
17631        }
17632        mLastMemoryLevel = memFactor;
17633        mLastNumProcesses = mLruProcesses.size();
17634        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17635        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17636        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17637            if (mLowRamStartTime == 0) {
17638                mLowRamStartTime = now;
17639            }
17640            int step = 0;
17641            int fgTrimLevel;
17642            switch (memFactor) {
17643                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17644                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17645                    break;
17646                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17647                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17648                    break;
17649                default:
17650                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17651                    break;
17652            }
17653            int factor = numTrimming/3;
17654            int minFactor = 2;
17655            if (mHomeProcess != null) minFactor++;
17656            if (mPreviousProcess != null) minFactor++;
17657            if (factor < minFactor) factor = minFactor;
17658            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17659            for (int i=N-1; i>=0; i--) {
17660                ProcessRecord app = mLruProcesses.get(i);
17661                if (allChanged || app.procStateChanged) {
17662                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17663                    app.procStateChanged = false;
17664                }
17665                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17666                        && !app.killedByAm) {
17667                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17668                        try {
17669                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17670                                    "Trimming memory of " + app.processName
17671                                    + " to " + curLevel);
17672                            app.thread.scheduleTrimMemory(curLevel);
17673                        } catch (RemoteException e) {
17674                        }
17675                        if (false) {
17676                            // For now we won't do this; our memory trimming seems
17677                            // to be good enough at this point that destroying
17678                            // activities causes more harm than good.
17679                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17680                                    && app != mHomeProcess && app != mPreviousProcess) {
17681                                // Need to do this on its own message because the stack may not
17682                                // be in a consistent state at this point.
17683                                // For these apps we will also finish their activities
17684                                // to help them free memory.
17685                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17686                            }
17687                        }
17688                    }
17689                    app.trimMemoryLevel = curLevel;
17690                    step++;
17691                    if (step >= factor) {
17692                        step = 0;
17693                        switch (curLevel) {
17694                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17695                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17696                                break;
17697                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17698                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17699                                break;
17700                        }
17701                    }
17702                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17703                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17704                            && app.thread != null) {
17705                        try {
17706                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17707                                    "Trimming memory of heavy-weight " + app.processName
17708                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17709                            app.thread.scheduleTrimMemory(
17710                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17711                        } catch (RemoteException e) {
17712                        }
17713                    }
17714                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17715                } else {
17716                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17717                            || app.systemNoUi) && app.pendingUiClean) {
17718                        // If this application is now in the background and it
17719                        // had done UI, then give it the special trim level to
17720                        // have it free UI resources.
17721                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17722                        if (app.trimMemoryLevel < level && app.thread != null) {
17723                            try {
17724                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17725                                        "Trimming memory of bg-ui " + app.processName
17726                                        + " to " + level);
17727                                app.thread.scheduleTrimMemory(level);
17728                            } catch (RemoteException e) {
17729                            }
17730                        }
17731                        app.pendingUiClean = false;
17732                    }
17733                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17734                        try {
17735                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17736                                    "Trimming memory of fg " + app.processName
17737                                    + " to " + fgTrimLevel);
17738                            app.thread.scheduleTrimMemory(fgTrimLevel);
17739                        } catch (RemoteException e) {
17740                        }
17741                    }
17742                    app.trimMemoryLevel = fgTrimLevel;
17743                }
17744            }
17745        } else {
17746            if (mLowRamStartTime != 0) {
17747                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17748                mLowRamStartTime = 0;
17749            }
17750            for (int i=N-1; i>=0; i--) {
17751                ProcessRecord app = mLruProcesses.get(i);
17752                if (allChanged || app.procStateChanged) {
17753                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17754                    app.procStateChanged = false;
17755                }
17756                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17757                        || app.systemNoUi) && app.pendingUiClean) {
17758                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17759                            && app.thread != null) {
17760                        try {
17761                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17762                                    "Trimming memory of ui hidden " + app.processName
17763                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17764                            app.thread.scheduleTrimMemory(
17765                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17766                        } catch (RemoteException e) {
17767                        }
17768                    }
17769                    app.pendingUiClean = false;
17770                }
17771                app.trimMemoryLevel = 0;
17772            }
17773        }
17774
17775        if (mAlwaysFinishActivities) {
17776            // Need to do this on its own message because the stack may not
17777            // be in a consistent state at this point.
17778            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17779        }
17780
17781        if (allChanged) {
17782            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17783        }
17784
17785        if (mProcessStats.shouldWriteNowLocked(now)) {
17786            mHandler.post(new Runnable() {
17787                @Override public void run() {
17788                    synchronized (ActivityManagerService.this) {
17789                        mProcessStats.writeStateAsyncLocked();
17790                    }
17791                }
17792            });
17793        }
17794
17795        if (DEBUG_OOM_ADJ) {
17796            if (false) {
17797                RuntimeException here = new RuntimeException("here");
17798                here.fillInStackTrace();
17799                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17800            } else {
17801                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17802            }
17803        }
17804    }
17805
17806    final void trimApplications() {
17807        synchronized (this) {
17808            int i;
17809
17810            // First remove any unused application processes whose package
17811            // has been removed.
17812            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17813                final ProcessRecord app = mRemovedProcesses.get(i);
17814                if (app.activities.size() == 0
17815                        && app.curReceiver == null && app.services.size() == 0) {
17816                    Slog.i(
17817                        TAG, "Exiting empty application process "
17818                        + app.processName + " ("
17819                        + (app.thread != null ? app.thread.asBinder() : null)
17820                        + ")\n");
17821                    if (app.pid > 0 && app.pid != MY_PID) {
17822                        app.kill("empty", false);
17823                    } else {
17824                        try {
17825                            app.thread.scheduleExit();
17826                        } catch (Exception e) {
17827                            // Ignore exceptions.
17828                        }
17829                    }
17830                    cleanUpApplicationRecordLocked(app, false, true, -1);
17831                    mRemovedProcesses.remove(i);
17832
17833                    if (app.persistent) {
17834                        addAppLocked(app.info, false, null /* ABI override */);
17835                    }
17836                }
17837            }
17838
17839            // Now update the oom adj for all processes.
17840            updateOomAdjLocked();
17841        }
17842    }
17843
17844    /** This method sends the specified signal to each of the persistent apps */
17845    public void signalPersistentProcesses(int sig) throws RemoteException {
17846        if (sig != Process.SIGNAL_USR1) {
17847            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17848        }
17849
17850        synchronized (this) {
17851            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17852                    != PackageManager.PERMISSION_GRANTED) {
17853                throw new SecurityException("Requires permission "
17854                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17855            }
17856
17857            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17858                ProcessRecord r = mLruProcesses.get(i);
17859                if (r.thread != null && r.persistent) {
17860                    Process.sendSignal(r.pid, sig);
17861                }
17862            }
17863        }
17864    }
17865
17866    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17867        if (proc == null || proc == mProfileProc) {
17868            proc = mProfileProc;
17869            profileType = mProfileType;
17870            clearProfilerLocked();
17871        }
17872        if (proc == null) {
17873            return;
17874        }
17875        try {
17876            proc.thread.profilerControl(false, null, profileType);
17877        } catch (RemoteException e) {
17878            throw new IllegalStateException("Process disappeared");
17879        }
17880    }
17881
17882    private void clearProfilerLocked() {
17883        if (mProfileFd != null) {
17884            try {
17885                mProfileFd.close();
17886            } catch (IOException e) {
17887            }
17888        }
17889        mProfileApp = null;
17890        mProfileProc = null;
17891        mProfileFile = null;
17892        mProfileType = 0;
17893        mAutoStopProfiler = false;
17894        mSamplingInterval = 0;
17895    }
17896
17897    public boolean profileControl(String process, int userId, boolean start,
17898            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17899
17900        try {
17901            synchronized (this) {
17902                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17903                // its own permission.
17904                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17905                        != PackageManager.PERMISSION_GRANTED) {
17906                    throw new SecurityException("Requires permission "
17907                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17908                }
17909
17910                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17911                    throw new IllegalArgumentException("null profile info or fd");
17912                }
17913
17914                ProcessRecord proc = null;
17915                if (process != null) {
17916                    proc = findProcessLocked(process, userId, "profileControl");
17917                }
17918
17919                if (start && (proc == null || proc.thread == null)) {
17920                    throw new IllegalArgumentException("Unknown process: " + process);
17921                }
17922
17923                if (start) {
17924                    stopProfilerLocked(null, 0);
17925                    setProfileApp(proc.info, proc.processName, profilerInfo);
17926                    mProfileProc = proc;
17927                    mProfileType = profileType;
17928                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17929                    try {
17930                        fd = fd.dup();
17931                    } catch (IOException e) {
17932                        fd = null;
17933                    }
17934                    profilerInfo.profileFd = fd;
17935                    proc.thread.profilerControl(start, profilerInfo, profileType);
17936                    fd = null;
17937                    mProfileFd = null;
17938                } else {
17939                    stopProfilerLocked(proc, profileType);
17940                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17941                        try {
17942                            profilerInfo.profileFd.close();
17943                        } catch (IOException e) {
17944                        }
17945                    }
17946                }
17947
17948                return true;
17949            }
17950        } catch (RemoteException e) {
17951            throw new IllegalStateException("Process disappeared");
17952        } finally {
17953            if (profilerInfo != null && profilerInfo.profileFd != null) {
17954                try {
17955                    profilerInfo.profileFd.close();
17956                } catch (IOException e) {
17957                }
17958            }
17959        }
17960    }
17961
17962    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17963        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17964                userId, true, ALLOW_FULL_ONLY, callName, null);
17965        ProcessRecord proc = null;
17966        try {
17967            int pid = Integer.parseInt(process);
17968            synchronized (mPidsSelfLocked) {
17969                proc = mPidsSelfLocked.get(pid);
17970            }
17971        } catch (NumberFormatException e) {
17972        }
17973
17974        if (proc == null) {
17975            ArrayMap<String, SparseArray<ProcessRecord>> all
17976                    = mProcessNames.getMap();
17977            SparseArray<ProcessRecord> procs = all.get(process);
17978            if (procs != null && procs.size() > 0) {
17979                proc = procs.valueAt(0);
17980                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17981                    for (int i=1; i<procs.size(); i++) {
17982                        ProcessRecord thisProc = procs.valueAt(i);
17983                        if (thisProc.userId == userId) {
17984                            proc = thisProc;
17985                            break;
17986                        }
17987                    }
17988                }
17989            }
17990        }
17991
17992        return proc;
17993    }
17994
17995    public boolean dumpHeap(String process, int userId, boolean managed,
17996            String path, ParcelFileDescriptor fd) throws RemoteException {
17997
17998        try {
17999            synchronized (this) {
18000                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18001                // its own permission (same as profileControl).
18002                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18003                        != PackageManager.PERMISSION_GRANTED) {
18004                    throw new SecurityException("Requires permission "
18005                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18006                }
18007
18008                if (fd == null) {
18009                    throw new IllegalArgumentException("null fd");
18010                }
18011
18012                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18013                if (proc == null || proc.thread == null) {
18014                    throw new IllegalArgumentException("Unknown process: " + process);
18015                }
18016
18017                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18018                if (!isDebuggable) {
18019                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18020                        throw new SecurityException("Process not debuggable: " + proc);
18021                    }
18022                }
18023
18024                proc.thread.dumpHeap(managed, path, fd);
18025                fd = null;
18026                return true;
18027            }
18028        } catch (RemoteException e) {
18029            throw new IllegalStateException("Process disappeared");
18030        } finally {
18031            if (fd != null) {
18032                try {
18033                    fd.close();
18034                } catch (IOException e) {
18035                }
18036            }
18037        }
18038    }
18039
18040    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18041    public void monitor() {
18042        synchronized (this) { }
18043    }
18044
18045    void onCoreSettingsChange(Bundle settings) {
18046        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18047            ProcessRecord processRecord = mLruProcesses.get(i);
18048            try {
18049                if (processRecord.thread != null) {
18050                    processRecord.thread.setCoreSettings(settings);
18051                }
18052            } catch (RemoteException re) {
18053                /* ignore */
18054            }
18055        }
18056    }
18057
18058    // Multi-user methods
18059
18060    /**
18061     * Start user, if its not already running, but don't bring it to foreground.
18062     */
18063    @Override
18064    public boolean startUserInBackground(final int userId) {
18065        return startUser(userId, /* foreground */ false);
18066    }
18067
18068    /**
18069     * Start user, if its not already running, and bring it to foreground.
18070     */
18071    boolean startUserInForeground(final int userId, Dialog dlg) {
18072        boolean result = startUser(userId, /* foreground */ true);
18073        dlg.dismiss();
18074        return result;
18075    }
18076
18077    /**
18078     * Refreshes the list of users related to the current user when either a
18079     * user switch happens or when a new related user is started in the
18080     * background.
18081     */
18082    private void updateCurrentProfileIdsLocked() {
18083        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18084                mCurrentUserId, false /* enabledOnly */);
18085        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18086        for (int i = 0; i < currentProfileIds.length; i++) {
18087            currentProfileIds[i] = profiles.get(i).id;
18088        }
18089        mCurrentProfileIds = currentProfileIds;
18090
18091        synchronized (mUserProfileGroupIdsSelfLocked) {
18092            mUserProfileGroupIdsSelfLocked.clear();
18093            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18094            for (int i = 0; i < users.size(); i++) {
18095                UserInfo user = users.get(i);
18096                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18097                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18098                }
18099            }
18100        }
18101    }
18102
18103    private Set getProfileIdsLocked(int userId) {
18104        Set userIds = new HashSet<Integer>();
18105        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18106                userId, false /* enabledOnly */);
18107        for (UserInfo user : profiles) {
18108            userIds.add(Integer.valueOf(user.id));
18109        }
18110        return userIds;
18111    }
18112
18113    @Override
18114    public boolean switchUser(final int userId) {
18115        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18116        String userName;
18117        synchronized (this) {
18118            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18119            if (userInfo == null) {
18120                Slog.w(TAG, "No user info for user #" + userId);
18121                return false;
18122            }
18123            if (userInfo.isManagedProfile()) {
18124                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18125                return false;
18126            }
18127            userName = userInfo.name;
18128            mTargetUserId = userId;
18129        }
18130        mHandler.removeMessages(START_USER_SWITCH_MSG);
18131        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18132        return true;
18133    }
18134
18135    private void showUserSwitchDialog(int userId, String userName) {
18136        // The dialog will show and then initiate the user switch by calling startUserInForeground
18137        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18138                true /* above system */);
18139        d.show();
18140    }
18141
18142    private boolean startUser(final int userId, final boolean foreground) {
18143        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18144                != PackageManager.PERMISSION_GRANTED) {
18145            String msg = "Permission Denial: switchUser() from pid="
18146                    + Binder.getCallingPid()
18147                    + ", uid=" + Binder.getCallingUid()
18148                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18149            Slog.w(TAG, msg);
18150            throw new SecurityException(msg);
18151        }
18152
18153        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18154
18155        final long ident = Binder.clearCallingIdentity();
18156        try {
18157            synchronized (this) {
18158                final int oldUserId = mCurrentUserId;
18159                if (oldUserId == userId) {
18160                    return true;
18161                }
18162
18163                mStackSupervisor.setLockTaskModeLocked(null, false);
18164
18165                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18166                if (userInfo == null) {
18167                    Slog.w(TAG, "No user info for user #" + userId);
18168                    return false;
18169                }
18170                if (foreground && userInfo.isManagedProfile()) {
18171                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18172                    return false;
18173                }
18174
18175                if (foreground) {
18176                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18177                            R.anim.screen_user_enter);
18178                }
18179
18180                boolean needStart = false;
18181
18182                // If the user we are switching to is not currently started, then
18183                // we need to start it now.
18184                if (mStartedUsers.get(userId) == null) {
18185                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18186                    updateStartedUserArrayLocked();
18187                    needStart = true;
18188                }
18189
18190                final Integer userIdInt = Integer.valueOf(userId);
18191                mUserLru.remove(userIdInt);
18192                mUserLru.add(userIdInt);
18193
18194                if (foreground) {
18195                    mCurrentUserId = userId;
18196                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18197                    updateCurrentProfileIdsLocked();
18198                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18199                    // Once the internal notion of the active user has switched, we lock the device
18200                    // with the option to show the user switcher on the keyguard.
18201                    mWindowManager.lockNow(null);
18202                } else {
18203                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18204                    updateCurrentProfileIdsLocked();
18205                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18206                    mUserLru.remove(currentUserIdInt);
18207                    mUserLru.add(currentUserIdInt);
18208                }
18209
18210                final UserStartedState uss = mStartedUsers.get(userId);
18211
18212                // Make sure user is in the started state.  If it is currently
18213                // stopping, we need to knock that off.
18214                if (uss.mState == UserStartedState.STATE_STOPPING) {
18215                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18216                    // so we can just fairly silently bring the user back from
18217                    // the almost-dead.
18218                    uss.mState = UserStartedState.STATE_RUNNING;
18219                    updateStartedUserArrayLocked();
18220                    needStart = true;
18221                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18222                    // This means ACTION_SHUTDOWN has been sent, so we will
18223                    // need to treat this as a new boot of the user.
18224                    uss.mState = UserStartedState.STATE_BOOTING;
18225                    updateStartedUserArrayLocked();
18226                    needStart = true;
18227                }
18228
18229                if (uss.mState == UserStartedState.STATE_BOOTING) {
18230                    // Booting up a new user, need to tell system services about it.
18231                    // Note that this is on the same handler as scheduling of broadcasts,
18232                    // which is important because it needs to go first.
18233                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18234                }
18235
18236                if (foreground) {
18237                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18238                            oldUserId));
18239                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18240                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18241                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18242                            oldUserId, userId, uss));
18243                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18244                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18245                }
18246
18247                if (needStart) {
18248                    // Send USER_STARTED broadcast
18249                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18250                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18251                            | Intent.FLAG_RECEIVER_FOREGROUND);
18252                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18253                    broadcastIntentLocked(null, null, intent,
18254                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18255                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18256                }
18257
18258                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18259                    if (userId != UserHandle.USER_OWNER) {
18260                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18261                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18262                        broadcastIntentLocked(null, null, intent, null,
18263                                new IIntentReceiver.Stub() {
18264                                    public void performReceive(Intent intent, int resultCode,
18265                                            String data, Bundle extras, boolean ordered,
18266                                            boolean sticky, int sendingUser) {
18267                                        onUserInitialized(uss, foreground, oldUserId, userId);
18268                                    }
18269                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18270                                true, false, MY_PID, Process.SYSTEM_UID,
18271                                userId);
18272                        uss.initializing = true;
18273                    } else {
18274                        getUserManagerLocked().makeInitialized(userInfo.id);
18275                    }
18276                }
18277
18278                if (foreground) {
18279                    if (!uss.initializing) {
18280                        moveUserToForeground(uss, oldUserId, userId);
18281                    }
18282                } else {
18283                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18284                }
18285
18286                if (needStart) {
18287                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18288                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18289                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18290                    broadcastIntentLocked(null, null, intent,
18291                            null, new IIntentReceiver.Stub() {
18292                                @Override
18293                                public void performReceive(Intent intent, int resultCode, String data,
18294                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18295                                        throws RemoteException {
18296                                }
18297                            }, 0, null, null,
18298                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18299                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18300                }
18301            }
18302        } finally {
18303            Binder.restoreCallingIdentity(ident);
18304        }
18305
18306        return true;
18307    }
18308
18309    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18310        long ident = Binder.clearCallingIdentity();
18311        try {
18312            Intent intent;
18313            if (oldUserId >= 0) {
18314                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18315                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18316                int count = profiles.size();
18317                for (int i = 0; i < count; i++) {
18318                    int profileUserId = profiles.get(i).id;
18319                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18320                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18321                            | Intent.FLAG_RECEIVER_FOREGROUND);
18322                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18323                    broadcastIntentLocked(null, null, intent,
18324                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18325                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18326                }
18327            }
18328            if (newUserId >= 0) {
18329                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18330                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18331                int count = profiles.size();
18332                for (int i = 0; i < count; i++) {
18333                    int profileUserId = profiles.get(i).id;
18334                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18335                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18336                            | Intent.FLAG_RECEIVER_FOREGROUND);
18337                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18338                    broadcastIntentLocked(null, null, intent,
18339                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18340                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18341                }
18342                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18343                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18344                        | Intent.FLAG_RECEIVER_FOREGROUND);
18345                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18346                broadcastIntentLocked(null, null, intent,
18347                        null, null, 0, null, null,
18348                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18349                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18350            }
18351        } finally {
18352            Binder.restoreCallingIdentity(ident);
18353        }
18354    }
18355
18356    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18357            final int newUserId) {
18358        final int N = mUserSwitchObservers.beginBroadcast();
18359        if (N > 0) {
18360            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18361                int mCount = 0;
18362                @Override
18363                public void sendResult(Bundle data) throws RemoteException {
18364                    synchronized (ActivityManagerService.this) {
18365                        if (mCurUserSwitchCallback == this) {
18366                            mCount++;
18367                            if (mCount == N) {
18368                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18369                            }
18370                        }
18371                    }
18372                }
18373            };
18374            synchronized (this) {
18375                uss.switching = true;
18376                mCurUserSwitchCallback = callback;
18377            }
18378            for (int i=0; i<N; i++) {
18379                try {
18380                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18381                            newUserId, callback);
18382                } catch (RemoteException e) {
18383                }
18384            }
18385        } else {
18386            synchronized (this) {
18387                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18388            }
18389        }
18390        mUserSwitchObservers.finishBroadcast();
18391    }
18392
18393    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18394        synchronized (this) {
18395            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18396            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18397        }
18398    }
18399
18400    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18401        mCurUserSwitchCallback = null;
18402        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18403        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18404                oldUserId, newUserId, uss));
18405    }
18406
18407    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18408        synchronized (this) {
18409            if (foreground) {
18410                moveUserToForeground(uss, oldUserId, newUserId);
18411            }
18412        }
18413
18414        completeSwitchAndInitalize(uss, newUserId, true, false);
18415    }
18416
18417    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18418        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18419        if (homeInFront) {
18420            startHomeActivityLocked(newUserId);
18421        } else {
18422            mStackSupervisor.resumeTopActivitiesLocked();
18423        }
18424        EventLogTags.writeAmSwitchUser(newUserId);
18425        getUserManagerLocked().userForeground(newUserId);
18426        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18427    }
18428
18429    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18430        completeSwitchAndInitalize(uss, newUserId, false, true);
18431    }
18432
18433    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18434            boolean clearInitializing, boolean clearSwitching) {
18435        boolean unfrozen = false;
18436        synchronized (this) {
18437            if (clearInitializing) {
18438                uss.initializing = false;
18439                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18440            }
18441            if (clearSwitching) {
18442                uss.switching = false;
18443            }
18444            if (!uss.switching && !uss.initializing) {
18445                mWindowManager.stopFreezingScreen();
18446                unfrozen = true;
18447            }
18448        }
18449        if (unfrozen) {
18450            final int N = mUserSwitchObservers.beginBroadcast();
18451            for (int i=0; i<N; i++) {
18452                try {
18453                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18454                } catch (RemoteException e) {
18455                }
18456            }
18457            mUserSwitchObservers.finishBroadcast();
18458        }
18459    }
18460
18461    void scheduleStartProfilesLocked() {
18462        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18463            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18464                    DateUtils.SECOND_IN_MILLIS);
18465        }
18466    }
18467
18468    void startProfilesLocked() {
18469        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18470        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18471                mCurrentUserId, false /* enabledOnly */);
18472        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18473        for (UserInfo user : profiles) {
18474            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18475                    && user.id != mCurrentUserId) {
18476                toStart.add(user);
18477            }
18478        }
18479        final int n = toStart.size();
18480        int i = 0;
18481        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18482            startUserInBackground(toStart.get(i).id);
18483        }
18484        if (i < n) {
18485            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18486        }
18487    }
18488
18489    void finishUserBoot(UserStartedState uss) {
18490        synchronized (this) {
18491            if (uss.mState == UserStartedState.STATE_BOOTING
18492                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18493                uss.mState = UserStartedState.STATE_RUNNING;
18494                final int userId = uss.mHandle.getIdentifier();
18495                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18496                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18497                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18498                broadcastIntentLocked(null, null, intent,
18499                        null, null, 0, null, null,
18500                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18501                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18502            }
18503        }
18504    }
18505
18506    void finishUserSwitch(UserStartedState uss) {
18507        synchronized (this) {
18508            finishUserBoot(uss);
18509
18510            startProfilesLocked();
18511
18512            int num = mUserLru.size();
18513            int i = 0;
18514            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18515                Integer oldUserId = mUserLru.get(i);
18516                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18517                if (oldUss == null) {
18518                    // Shouldn't happen, but be sane if it does.
18519                    mUserLru.remove(i);
18520                    num--;
18521                    continue;
18522                }
18523                if (oldUss.mState == UserStartedState.STATE_STOPPING
18524                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18525                    // This user is already stopping, doesn't count.
18526                    num--;
18527                    i++;
18528                    continue;
18529                }
18530                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18531                    // Owner and current can't be stopped, but count as running.
18532                    i++;
18533                    continue;
18534                }
18535                // This is a user to be stopped.
18536                stopUserLocked(oldUserId, null);
18537                num--;
18538                i++;
18539            }
18540        }
18541    }
18542
18543    @Override
18544    public int stopUser(final int userId, final IStopUserCallback callback) {
18545        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18546                != PackageManager.PERMISSION_GRANTED) {
18547            String msg = "Permission Denial: switchUser() from pid="
18548                    + Binder.getCallingPid()
18549                    + ", uid=" + Binder.getCallingUid()
18550                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18551            Slog.w(TAG, msg);
18552            throw new SecurityException(msg);
18553        }
18554        if (userId <= 0) {
18555            throw new IllegalArgumentException("Can't stop primary user " + userId);
18556        }
18557        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18558        synchronized (this) {
18559            return stopUserLocked(userId, callback);
18560        }
18561    }
18562
18563    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18564        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18565        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18566            return ActivityManager.USER_OP_IS_CURRENT;
18567        }
18568
18569        final UserStartedState uss = mStartedUsers.get(userId);
18570        if (uss == null) {
18571            // User is not started, nothing to do...  but we do need to
18572            // callback if requested.
18573            if (callback != null) {
18574                mHandler.post(new Runnable() {
18575                    @Override
18576                    public void run() {
18577                        try {
18578                            callback.userStopped(userId);
18579                        } catch (RemoteException e) {
18580                        }
18581                    }
18582                });
18583            }
18584            return ActivityManager.USER_OP_SUCCESS;
18585        }
18586
18587        if (callback != null) {
18588            uss.mStopCallbacks.add(callback);
18589        }
18590
18591        if (uss.mState != UserStartedState.STATE_STOPPING
18592                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18593            uss.mState = UserStartedState.STATE_STOPPING;
18594            updateStartedUserArrayLocked();
18595
18596            long ident = Binder.clearCallingIdentity();
18597            try {
18598                // We are going to broadcast ACTION_USER_STOPPING and then
18599                // once that is done send a final ACTION_SHUTDOWN and then
18600                // stop the user.
18601                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18602                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18603                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18604                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18605                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18606                // This is the result receiver for the final shutdown broadcast.
18607                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18608                    @Override
18609                    public void performReceive(Intent intent, int resultCode, String data,
18610                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18611                        finishUserStop(uss);
18612                    }
18613                };
18614                // This is the result receiver for the initial stopping broadcast.
18615                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18616                    @Override
18617                    public void performReceive(Intent intent, int resultCode, String data,
18618                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18619                        // On to the next.
18620                        synchronized (ActivityManagerService.this) {
18621                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18622                                // Whoops, we are being started back up.  Abort, abort!
18623                                return;
18624                            }
18625                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18626                        }
18627                        mBatteryStatsService.noteEvent(
18628                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18629                                Integer.toString(userId), userId);
18630                        mSystemServiceManager.stopUser(userId);
18631                        broadcastIntentLocked(null, null, shutdownIntent,
18632                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18633                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18634                    }
18635                };
18636                // Kick things off.
18637                broadcastIntentLocked(null, null, stoppingIntent,
18638                        null, stoppingReceiver, 0, null, null,
18639                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18640                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18641            } finally {
18642                Binder.restoreCallingIdentity(ident);
18643            }
18644        }
18645
18646        return ActivityManager.USER_OP_SUCCESS;
18647    }
18648
18649    void finishUserStop(UserStartedState uss) {
18650        final int userId = uss.mHandle.getIdentifier();
18651        boolean stopped;
18652        ArrayList<IStopUserCallback> callbacks;
18653        synchronized (this) {
18654            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18655            if (mStartedUsers.get(userId) != uss) {
18656                stopped = false;
18657            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18658                stopped = false;
18659            } else {
18660                stopped = true;
18661                // User can no longer run.
18662                mStartedUsers.remove(userId);
18663                mUserLru.remove(Integer.valueOf(userId));
18664                updateStartedUserArrayLocked();
18665
18666                // Clean up all state and processes associated with the user.
18667                // Kill all the processes for the user.
18668                forceStopUserLocked(userId, "finish user");
18669            }
18670
18671            // Explicitly remove the old information in mRecentTasks.
18672            removeRecentTasksForUserLocked(userId);
18673        }
18674
18675        for (int i=0; i<callbacks.size(); i++) {
18676            try {
18677                if (stopped) callbacks.get(i).userStopped(userId);
18678                else callbacks.get(i).userStopAborted(userId);
18679            } catch (RemoteException e) {
18680            }
18681        }
18682
18683        if (stopped) {
18684            mSystemServiceManager.cleanupUser(userId);
18685            synchronized (this) {
18686                mStackSupervisor.removeUserLocked(userId);
18687            }
18688        }
18689    }
18690
18691    @Override
18692    public UserInfo getCurrentUser() {
18693        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18694                != PackageManager.PERMISSION_GRANTED) && (
18695                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18696                != PackageManager.PERMISSION_GRANTED)) {
18697            String msg = "Permission Denial: getCurrentUser() from pid="
18698                    + Binder.getCallingPid()
18699                    + ", uid=" + Binder.getCallingUid()
18700                    + " requires " + INTERACT_ACROSS_USERS;
18701            Slog.w(TAG, msg);
18702            throw new SecurityException(msg);
18703        }
18704        synchronized (this) {
18705            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18706            return getUserManagerLocked().getUserInfo(userId);
18707        }
18708    }
18709
18710    int getCurrentUserIdLocked() {
18711        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18712    }
18713
18714    @Override
18715    public boolean isUserRunning(int userId, boolean orStopped) {
18716        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18717                != PackageManager.PERMISSION_GRANTED) {
18718            String msg = "Permission Denial: isUserRunning() from pid="
18719                    + Binder.getCallingPid()
18720                    + ", uid=" + Binder.getCallingUid()
18721                    + " requires " + INTERACT_ACROSS_USERS;
18722            Slog.w(TAG, msg);
18723            throw new SecurityException(msg);
18724        }
18725        synchronized (this) {
18726            return isUserRunningLocked(userId, orStopped);
18727        }
18728    }
18729
18730    boolean isUserRunningLocked(int userId, boolean orStopped) {
18731        UserStartedState state = mStartedUsers.get(userId);
18732        if (state == null) {
18733            return false;
18734        }
18735        if (orStopped) {
18736            return true;
18737        }
18738        return state.mState != UserStartedState.STATE_STOPPING
18739                && state.mState != UserStartedState.STATE_SHUTDOWN;
18740    }
18741
18742    @Override
18743    public int[] getRunningUserIds() {
18744        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18745                != PackageManager.PERMISSION_GRANTED) {
18746            String msg = "Permission Denial: isUserRunning() from pid="
18747                    + Binder.getCallingPid()
18748                    + ", uid=" + Binder.getCallingUid()
18749                    + " requires " + INTERACT_ACROSS_USERS;
18750            Slog.w(TAG, msg);
18751            throw new SecurityException(msg);
18752        }
18753        synchronized (this) {
18754            return mStartedUserArray;
18755        }
18756    }
18757
18758    private void updateStartedUserArrayLocked() {
18759        int num = 0;
18760        for (int i=0; i<mStartedUsers.size();  i++) {
18761            UserStartedState uss = mStartedUsers.valueAt(i);
18762            // This list does not include stopping users.
18763            if (uss.mState != UserStartedState.STATE_STOPPING
18764                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18765                num++;
18766            }
18767        }
18768        mStartedUserArray = new int[num];
18769        num = 0;
18770        for (int i=0; i<mStartedUsers.size();  i++) {
18771            UserStartedState uss = mStartedUsers.valueAt(i);
18772            if (uss.mState != UserStartedState.STATE_STOPPING
18773                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18774                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18775                num++;
18776            }
18777        }
18778    }
18779
18780    @Override
18781    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18782        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18783                != PackageManager.PERMISSION_GRANTED) {
18784            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18785                    + Binder.getCallingPid()
18786                    + ", uid=" + Binder.getCallingUid()
18787                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18788            Slog.w(TAG, msg);
18789            throw new SecurityException(msg);
18790        }
18791
18792        mUserSwitchObservers.register(observer);
18793    }
18794
18795    @Override
18796    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18797        mUserSwitchObservers.unregister(observer);
18798    }
18799
18800    private boolean userExists(int userId) {
18801        if (userId == 0) {
18802            return true;
18803        }
18804        UserManagerService ums = getUserManagerLocked();
18805        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18806    }
18807
18808    int[] getUsersLocked() {
18809        UserManagerService ums = getUserManagerLocked();
18810        return ums != null ? ums.getUserIds() : new int[] { 0 };
18811    }
18812
18813    UserManagerService getUserManagerLocked() {
18814        if (mUserManager == null) {
18815            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18816            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18817        }
18818        return mUserManager;
18819    }
18820
18821    private int applyUserId(int uid, int userId) {
18822        return UserHandle.getUid(userId, uid);
18823    }
18824
18825    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18826        if (info == null) return null;
18827        ApplicationInfo newInfo = new ApplicationInfo(info);
18828        newInfo.uid = applyUserId(info.uid, userId);
18829        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18830                + info.packageName;
18831        return newInfo;
18832    }
18833
18834    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18835        if (aInfo == null
18836                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18837            return aInfo;
18838        }
18839
18840        ActivityInfo info = new ActivityInfo(aInfo);
18841        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18842        return info;
18843    }
18844
18845    private final class LocalService extends ActivityManagerInternal {
18846        @Override
18847        public void goingToSleep() {
18848            ActivityManagerService.this.goingToSleep();
18849        }
18850
18851        @Override
18852        public void wakingUp() {
18853            ActivityManagerService.this.wakingUp();
18854        }
18855
18856        @Override
18857        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18858                String processName, String abiOverride, int uid, Runnable crashHandler) {
18859            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18860                    processName, abiOverride, uid, crashHandler);
18861        }
18862    }
18863
18864    /**
18865     * An implementation of IAppTask, that allows an app to manage its own tasks via
18866     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18867     * only the process that calls getAppTasks() can call the AppTask methods.
18868     */
18869    class AppTaskImpl extends IAppTask.Stub {
18870        private int mTaskId;
18871        private int mCallingUid;
18872
18873        public AppTaskImpl(int taskId, int callingUid) {
18874            mTaskId = taskId;
18875            mCallingUid = callingUid;
18876        }
18877
18878        private void checkCaller() {
18879            if (mCallingUid != Binder.getCallingUid()) {
18880                throw new SecurityException("Caller " + mCallingUid
18881                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18882            }
18883        }
18884
18885        @Override
18886        public void finishAndRemoveTask() {
18887            checkCaller();
18888
18889            synchronized (ActivityManagerService.this) {
18890                long origId = Binder.clearCallingIdentity();
18891                try {
18892                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18893                    if (tr == null) {
18894                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18895                    }
18896                    // Only kill the process if we are not a new document
18897                    int flags = tr.getBaseIntent().getFlags();
18898                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18899                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18900                    removeTaskByIdLocked(mTaskId,
18901                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18902                } finally {
18903                    Binder.restoreCallingIdentity(origId);
18904                }
18905            }
18906        }
18907
18908        @Override
18909        public ActivityManager.RecentTaskInfo getTaskInfo() {
18910            checkCaller();
18911
18912            synchronized (ActivityManagerService.this) {
18913                long origId = Binder.clearCallingIdentity();
18914                try {
18915                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18916                    if (tr == null) {
18917                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18918                    }
18919                    return createRecentTaskInfoFromTaskRecord(tr);
18920                } finally {
18921                    Binder.restoreCallingIdentity(origId);
18922                }
18923            }
18924        }
18925
18926        @Override
18927        public void moveToFront() {
18928            checkCaller();
18929
18930            final TaskRecord tr;
18931            synchronized (ActivityManagerService.this) {
18932                tr = recentTaskForIdLocked(mTaskId);
18933                if (tr == null) {
18934                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18935                }
18936                if (tr.getRootActivity() != null) {
18937                    long origId = Binder.clearCallingIdentity();
18938                    try {
18939                        moveTaskToFrontLocked(tr.taskId, 0, null);
18940                        return;
18941                    } finally {
18942                        Binder.restoreCallingIdentity(origId);
18943                    }
18944                }
18945            }
18946
18947            startActivityFromRecentsInner(tr.taskId, null);
18948        }
18949
18950        @Override
18951        public int startActivity(IBinder whoThread, String callingPackage,
18952                Intent intent, String resolvedType, Bundle options) {
18953            checkCaller();
18954
18955            int callingUser = UserHandle.getCallingUserId();
18956            TaskRecord tr;
18957            IApplicationThread appThread;
18958            synchronized (ActivityManagerService.this) {
18959                tr = recentTaskForIdLocked(mTaskId);
18960                if (tr == null) {
18961                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18962                }
18963                appThread = ApplicationThreadNative.asInterface(whoThread);
18964                if (appThread == null) {
18965                    throw new IllegalArgumentException("Bad app thread " + appThread);
18966                }
18967            }
18968            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18969                    resolvedType, null, null, null, null, 0, 0, null, null,
18970                    null, options, callingUser, null, tr);
18971        }
18972
18973        @Override
18974        public void setExcludeFromRecents(boolean exclude) {
18975            checkCaller();
18976
18977            synchronized (ActivityManagerService.this) {
18978                long origId = Binder.clearCallingIdentity();
18979                try {
18980                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18981                    if (tr == null) {
18982                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18983                    }
18984                    Intent intent = tr.getBaseIntent();
18985                    if (exclude) {
18986                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18987                    } else {
18988                        intent.setFlags(intent.getFlags()
18989                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18990                    }
18991                } finally {
18992                    Binder.restoreCallingIdentity(origId);
18993                }
18994            }
18995        }
18996    }
18997}
18998