ActivityManagerService.java revision 246a8bcadde961f6bc8172811a052af3568a6f4d
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, 0, 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,
3756                    -1, r.launchedFromUid, 0, 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                tracesDir.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                    tracesDir.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                if (mLockScreenShown) {
6246                    mLockScreenShown = false;
6247                    comeOutOfSleepIfNeededLocked();
6248                }
6249            }
6250        } finally {
6251            Binder.restoreCallingIdentity(token);
6252        }
6253    }
6254
6255    final void finishBooting() {
6256        synchronized (this) {
6257            if (!mBootAnimationComplete) {
6258                mCallFinishBooting = true;
6259                return;
6260            }
6261            mCallFinishBooting = false;
6262        }
6263
6264        // Register receivers to handle package update events
6265        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6266
6267        // Let system services know.
6268        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6269
6270        synchronized (this) {
6271            // Ensure that any processes we had put on hold are now started
6272            // up.
6273            final int NP = mProcessesOnHold.size();
6274            if (NP > 0) {
6275                ArrayList<ProcessRecord> procs =
6276                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6277                for (int ip=0; ip<NP; ip++) {
6278                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6279                            + procs.get(ip));
6280                    startProcessLocked(procs.get(ip), "on-hold", null);
6281                }
6282            }
6283
6284            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6285                // Start looking for apps that are abusing wake locks.
6286                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6287                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6288                // Tell anyone interested that we are done booting!
6289                SystemProperties.set("sys.boot_completed", "1");
6290                SystemProperties.set("dev.bootcomplete", "1");
6291                for (int i=0; i<mStartedUsers.size(); i++) {
6292                    UserStartedState uss = mStartedUsers.valueAt(i);
6293                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6294                        uss.mState = UserStartedState.STATE_RUNNING;
6295                        final int userId = mStartedUsers.keyAt(i);
6296                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6297                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6298                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6299                        broadcastIntentLocked(null, null, intent, null,
6300                                new IIntentReceiver.Stub() {
6301                                    @Override
6302                                    public void performReceive(Intent intent, int resultCode,
6303                                            String data, Bundle extras, boolean ordered,
6304                                            boolean sticky, int sendingUser) {
6305                                        synchronized (ActivityManagerService.this) {
6306                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6307                                                    true, false);
6308                                        }
6309                                    }
6310                                },
6311                                0, null, null,
6312                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6313                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6314                                userId);
6315                    }
6316                }
6317                scheduleStartProfilesLocked();
6318            }
6319        }
6320    }
6321
6322    @Override
6323    public void bootAnimationComplete() {
6324        final boolean callFinishBooting;
6325        synchronized (this) {
6326            callFinishBooting = mCallFinishBooting;
6327            mBootAnimationComplete = true;
6328        }
6329        if (callFinishBooting) {
6330            finishBooting();
6331        }
6332    }
6333
6334    final void ensureBootCompleted() {
6335        boolean booting;
6336        boolean enableScreen;
6337        synchronized (this) {
6338            booting = mBooting;
6339            mBooting = false;
6340            enableScreen = !mBooted;
6341            mBooted = true;
6342        }
6343
6344        if (booting) {
6345            finishBooting();
6346        }
6347
6348        if (enableScreen) {
6349            enableScreenAfterBoot();
6350        }
6351    }
6352
6353    @Override
6354    public final void activityResumed(IBinder token) {
6355        final long origId = Binder.clearCallingIdentity();
6356        synchronized(this) {
6357            ActivityStack stack = ActivityRecord.getStackLocked(token);
6358            if (stack != null) {
6359                ActivityRecord.activityResumedLocked(token);
6360            }
6361        }
6362        Binder.restoreCallingIdentity(origId);
6363    }
6364
6365    @Override
6366    public final void activityPaused(IBinder token) {
6367        final long origId = Binder.clearCallingIdentity();
6368        synchronized(this) {
6369            ActivityStack stack = ActivityRecord.getStackLocked(token);
6370            if (stack != null) {
6371                stack.activityPausedLocked(token, false);
6372            }
6373        }
6374        Binder.restoreCallingIdentity(origId);
6375    }
6376
6377    @Override
6378    public final void activityStopped(IBinder token, Bundle icicle,
6379            PersistableBundle persistentState, CharSequence description) {
6380        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6381
6382        // Refuse possible leaked file descriptors
6383        if (icicle != null && icicle.hasFileDescriptors()) {
6384            throw new IllegalArgumentException("File descriptors passed in Bundle");
6385        }
6386
6387        final long origId = Binder.clearCallingIdentity();
6388
6389        synchronized (this) {
6390            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6391            if (r != null) {
6392                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6393            }
6394        }
6395
6396        trimApplications();
6397
6398        Binder.restoreCallingIdentity(origId);
6399    }
6400
6401    @Override
6402    public final void activityDestroyed(IBinder token) {
6403        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6404        synchronized (this) {
6405            ActivityStack stack = ActivityRecord.getStackLocked(token);
6406            if (stack != null) {
6407                stack.activityDestroyedLocked(token);
6408            }
6409        }
6410    }
6411
6412    @Override
6413    public final void backgroundResourcesReleased(IBinder token) {
6414        final long origId = Binder.clearCallingIdentity();
6415        try {
6416            synchronized (this) {
6417                ActivityStack stack = ActivityRecord.getStackLocked(token);
6418                if (stack != null) {
6419                    stack.backgroundResourcesReleased(token);
6420                }
6421            }
6422        } finally {
6423            Binder.restoreCallingIdentity(origId);
6424        }
6425    }
6426
6427    @Override
6428    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6429        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6430    }
6431
6432    @Override
6433    public final void notifyEnterAnimationComplete(IBinder token) {
6434        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6435    }
6436
6437    @Override
6438    public String getCallingPackage(IBinder token) {
6439        synchronized (this) {
6440            ActivityRecord r = getCallingRecordLocked(token);
6441            return r != null ? r.info.packageName : null;
6442        }
6443    }
6444
6445    @Override
6446    public ComponentName getCallingActivity(IBinder token) {
6447        synchronized (this) {
6448            ActivityRecord r = getCallingRecordLocked(token);
6449            return r != null ? r.intent.getComponent() : null;
6450        }
6451    }
6452
6453    private ActivityRecord getCallingRecordLocked(IBinder token) {
6454        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6455        if (r == null) {
6456            return null;
6457        }
6458        return r.resultTo;
6459    }
6460
6461    @Override
6462    public ComponentName getActivityClassForToken(IBinder token) {
6463        synchronized(this) {
6464            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6465            if (r == null) {
6466                return null;
6467            }
6468            return r.intent.getComponent();
6469        }
6470    }
6471
6472    @Override
6473    public String getPackageForToken(IBinder token) {
6474        synchronized(this) {
6475            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6476            if (r == null) {
6477                return null;
6478            }
6479            return r.packageName;
6480        }
6481    }
6482
6483    @Override
6484    public IIntentSender getIntentSender(int type,
6485            String packageName, IBinder token, String resultWho,
6486            int requestCode, Intent[] intents, String[] resolvedTypes,
6487            int flags, Bundle options, int userId) {
6488        enforceNotIsolatedCaller("getIntentSender");
6489        // Refuse possible leaked file descriptors
6490        if (intents != null) {
6491            if (intents.length < 1) {
6492                throw new IllegalArgumentException("Intents array length must be >= 1");
6493            }
6494            for (int i=0; i<intents.length; i++) {
6495                Intent intent = intents[i];
6496                if (intent != null) {
6497                    if (intent.hasFileDescriptors()) {
6498                        throw new IllegalArgumentException("File descriptors passed in Intent");
6499                    }
6500                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6501                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6502                        throw new IllegalArgumentException(
6503                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6504                    }
6505                    intents[i] = new Intent(intent);
6506                }
6507            }
6508            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6509                throw new IllegalArgumentException(
6510                        "Intent array length does not match resolvedTypes length");
6511            }
6512        }
6513        if (options != null) {
6514            if (options.hasFileDescriptors()) {
6515                throw new IllegalArgumentException("File descriptors passed in options");
6516            }
6517        }
6518
6519        synchronized(this) {
6520            int callingUid = Binder.getCallingUid();
6521            int origUserId = userId;
6522            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6523                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6524                    ALLOW_NON_FULL, "getIntentSender", null);
6525            if (origUserId == UserHandle.USER_CURRENT) {
6526                // We don't want to evaluate this until the pending intent is
6527                // actually executed.  However, we do want to always do the
6528                // security checking for it above.
6529                userId = UserHandle.USER_CURRENT;
6530            }
6531            try {
6532                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6533                    int uid = AppGlobals.getPackageManager()
6534                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6535                    if (!UserHandle.isSameApp(callingUid, uid)) {
6536                        String msg = "Permission Denial: getIntentSender() from pid="
6537                            + Binder.getCallingPid()
6538                            + ", uid=" + Binder.getCallingUid()
6539                            + ", (need uid=" + uid + ")"
6540                            + " is not allowed to send as package " + packageName;
6541                        Slog.w(TAG, msg);
6542                        throw new SecurityException(msg);
6543                    }
6544                }
6545
6546                return getIntentSenderLocked(type, packageName, callingUid, userId,
6547                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6548
6549            } catch (RemoteException e) {
6550                throw new SecurityException(e);
6551            }
6552        }
6553    }
6554
6555    IIntentSender getIntentSenderLocked(int type, String packageName,
6556            int callingUid, int userId, IBinder token, String resultWho,
6557            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6558            Bundle options) {
6559        if (DEBUG_MU)
6560            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6561        ActivityRecord activity = null;
6562        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6563            activity = ActivityRecord.isInStackLocked(token);
6564            if (activity == null) {
6565                return null;
6566            }
6567            if (activity.finishing) {
6568                return null;
6569            }
6570        }
6571
6572        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6573        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6574        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6575        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6576                |PendingIntent.FLAG_UPDATE_CURRENT);
6577
6578        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6579                type, packageName, activity, resultWho,
6580                requestCode, intents, resolvedTypes, flags, options, userId);
6581        WeakReference<PendingIntentRecord> ref;
6582        ref = mIntentSenderRecords.get(key);
6583        PendingIntentRecord rec = ref != null ? ref.get() : null;
6584        if (rec != null) {
6585            if (!cancelCurrent) {
6586                if (updateCurrent) {
6587                    if (rec.key.requestIntent != null) {
6588                        rec.key.requestIntent.replaceExtras(intents != null ?
6589                                intents[intents.length - 1] : null);
6590                    }
6591                    if (intents != null) {
6592                        intents[intents.length-1] = rec.key.requestIntent;
6593                        rec.key.allIntents = intents;
6594                        rec.key.allResolvedTypes = resolvedTypes;
6595                    } else {
6596                        rec.key.allIntents = null;
6597                        rec.key.allResolvedTypes = null;
6598                    }
6599                }
6600                return rec;
6601            }
6602            rec.canceled = true;
6603            mIntentSenderRecords.remove(key);
6604        }
6605        if (noCreate) {
6606            return rec;
6607        }
6608        rec = new PendingIntentRecord(this, key, callingUid);
6609        mIntentSenderRecords.put(key, rec.ref);
6610        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6611            if (activity.pendingResults == null) {
6612                activity.pendingResults
6613                        = new HashSet<WeakReference<PendingIntentRecord>>();
6614            }
6615            activity.pendingResults.add(rec.ref);
6616        }
6617        return rec;
6618    }
6619
6620    @Override
6621    public void cancelIntentSender(IIntentSender sender) {
6622        if (!(sender instanceof PendingIntentRecord)) {
6623            return;
6624        }
6625        synchronized(this) {
6626            PendingIntentRecord rec = (PendingIntentRecord)sender;
6627            try {
6628                int uid = AppGlobals.getPackageManager()
6629                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6630                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6631                    String msg = "Permission Denial: cancelIntentSender() from pid="
6632                        + Binder.getCallingPid()
6633                        + ", uid=" + Binder.getCallingUid()
6634                        + " is not allowed to cancel packges "
6635                        + rec.key.packageName;
6636                    Slog.w(TAG, msg);
6637                    throw new SecurityException(msg);
6638                }
6639            } catch (RemoteException e) {
6640                throw new SecurityException(e);
6641            }
6642            cancelIntentSenderLocked(rec, true);
6643        }
6644    }
6645
6646    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6647        rec.canceled = true;
6648        mIntentSenderRecords.remove(rec.key);
6649        if (cleanActivity && rec.key.activity != null) {
6650            rec.key.activity.pendingResults.remove(rec.ref);
6651        }
6652    }
6653
6654    @Override
6655    public String getPackageForIntentSender(IIntentSender pendingResult) {
6656        if (!(pendingResult instanceof PendingIntentRecord)) {
6657            return null;
6658        }
6659        try {
6660            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6661            return res.key.packageName;
6662        } catch (ClassCastException e) {
6663        }
6664        return null;
6665    }
6666
6667    @Override
6668    public int getUidForIntentSender(IIntentSender sender) {
6669        if (sender instanceof PendingIntentRecord) {
6670            try {
6671                PendingIntentRecord res = (PendingIntentRecord)sender;
6672                return res.uid;
6673            } catch (ClassCastException e) {
6674            }
6675        }
6676        return -1;
6677    }
6678
6679    @Override
6680    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6681        if (!(pendingResult instanceof PendingIntentRecord)) {
6682            return false;
6683        }
6684        try {
6685            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6686            if (res.key.allIntents == null) {
6687                return false;
6688            }
6689            for (int i=0; i<res.key.allIntents.length; i++) {
6690                Intent intent = res.key.allIntents[i];
6691                if (intent.getPackage() != null && intent.getComponent() != null) {
6692                    return false;
6693                }
6694            }
6695            return true;
6696        } catch (ClassCastException e) {
6697        }
6698        return false;
6699    }
6700
6701    @Override
6702    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6703        if (!(pendingResult instanceof PendingIntentRecord)) {
6704            return false;
6705        }
6706        try {
6707            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6708            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6709                return true;
6710            }
6711            return false;
6712        } catch (ClassCastException e) {
6713        }
6714        return false;
6715    }
6716
6717    @Override
6718    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6719        if (!(pendingResult instanceof PendingIntentRecord)) {
6720            return null;
6721        }
6722        try {
6723            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6724            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6725        } catch (ClassCastException e) {
6726        }
6727        return null;
6728    }
6729
6730    @Override
6731    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6732        if (!(pendingResult instanceof PendingIntentRecord)) {
6733            return null;
6734        }
6735        try {
6736            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6737            Intent intent = res.key.requestIntent;
6738            if (intent != null) {
6739                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6740                        || res.lastTagPrefix.equals(prefix))) {
6741                    return res.lastTag;
6742                }
6743                res.lastTagPrefix = prefix;
6744                StringBuilder sb = new StringBuilder(128);
6745                if (prefix != null) {
6746                    sb.append(prefix);
6747                }
6748                if (intent.getAction() != null) {
6749                    sb.append(intent.getAction());
6750                } else if (intent.getComponent() != null) {
6751                    intent.getComponent().appendShortString(sb);
6752                } else {
6753                    sb.append("?");
6754                }
6755                return res.lastTag = sb.toString();
6756            }
6757        } catch (ClassCastException e) {
6758        }
6759        return null;
6760    }
6761
6762    @Override
6763    public void setProcessLimit(int max) {
6764        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6765                "setProcessLimit()");
6766        synchronized (this) {
6767            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6768            mProcessLimitOverride = max;
6769        }
6770        trimApplications();
6771    }
6772
6773    @Override
6774    public int getProcessLimit() {
6775        synchronized (this) {
6776            return mProcessLimitOverride;
6777        }
6778    }
6779
6780    void foregroundTokenDied(ForegroundToken token) {
6781        synchronized (ActivityManagerService.this) {
6782            synchronized (mPidsSelfLocked) {
6783                ForegroundToken cur
6784                    = mForegroundProcesses.get(token.pid);
6785                if (cur != token) {
6786                    return;
6787                }
6788                mForegroundProcesses.remove(token.pid);
6789                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6790                if (pr == null) {
6791                    return;
6792                }
6793                pr.forcingToForeground = null;
6794                updateProcessForegroundLocked(pr, false, false);
6795            }
6796            updateOomAdjLocked();
6797        }
6798    }
6799
6800    @Override
6801    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6802        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6803                "setProcessForeground()");
6804        synchronized(this) {
6805            boolean changed = false;
6806
6807            synchronized (mPidsSelfLocked) {
6808                ProcessRecord pr = mPidsSelfLocked.get(pid);
6809                if (pr == null && isForeground) {
6810                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6811                    return;
6812                }
6813                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6814                if (oldToken != null) {
6815                    oldToken.token.unlinkToDeath(oldToken, 0);
6816                    mForegroundProcesses.remove(pid);
6817                    if (pr != null) {
6818                        pr.forcingToForeground = null;
6819                    }
6820                    changed = true;
6821                }
6822                if (isForeground && token != null) {
6823                    ForegroundToken newToken = new ForegroundToken() {
6824                        @Override
6825                        public void binderDied() {
6826                            foregroundTokenDied(this);
6827                        }
6828                    };
6829                    newToken.pid = pid;
6830                    newToken.token = token;
6831                    try {
6832                        token.linkToDeath(newToken, 0);
6833                        mForegroundProcesses.put(pid, newToken);
6834                        pr.forcingToForeground = token;
6835                        changed = true;
6836                    } catch (RemoteException e) {
6837                        // If the process died while doing this, we will later
6838                        // do the cleanup with the process death link.
6839                    }
6840                }
6841            }
6842
6843            if (changed) {
6844                updateOomAdjLocked();
6845            }
6846        }
6847    }
6848
6849    // =========================================================
6850    // PERMISSIONS
6851    // =========================================================
6852
6853    static class PermissionController extends IPermissionController.Stub {
6854        ActivityManagerService mActivityManagerService;
6855        PermissionController(ActivityManagerService activityManagerService) {
6856            mActivityManagerService = activityManagerService;
6857        }
6858
6859        @Override
6860        public boolean checkPermission(String permission, int pid, int uid) {
6861            return mActivityManagerService.checkPermission(permission, pid,
6862                    uid) == PackageManager.PERMISSION_GRANTED;
6863        }
6864    }
6865
6866    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6867        @Override
6868        public int checkComponentPermission(String permission, int pid, int uid,
6869                int owningUid, boolean exported) {
6870            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6871                    owningUid, exported);
6872        }
6873
6874        @Override
6875        public Object getAMSLock() {
6876            return ActivityManagerService.this;
6877        }
6878    }
6879
6880    /**
6881     * This can be called with or without the global lock held.
6882     */
6883    int checkComponentPermission(String permission, int pid, int uid,
6884            int owningUid, boolean exported) {
6885        // We might be performing an operation on behalf of an indirect binder
6886        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6887        // client identity accordingly before proceeding.
6888        Identity tlsIdentity = sCallerIdentity.get();
6889        if (tlsIdentity != null) {
6890            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6891                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6892            uid = tlsIdentity.uid;
6893            pid = tlsIdentity.pid;
6894        }
6895
6896        if (pid == MY_PID) {
6897            return PackageManager.PERMISSION_GRANTED;
6898        }
6899
6900        return ActivityManager.checkComponentPermission(permission, uid,
6901                owningUid, exported);
6902    }
6903
6904    /**
6905     * As the only public entry point for permissions checking, this method
6906     * can enforce the semantic that requesting a check on a null global
6907     * permission is automatically denied.  (Internally a null permission
6908     * string is used when calling {@link #checkComponentPermission} in cases
6909     * when only uid-based security is needed.)
6910     *
6911     * This can be called with or without the global lock held.
6912     */
6913    @Override
6914    public int checkPermission(String permission, int pid, int uid) {
6915        if (permission == null) {
6916            return PackageManager.PERMISSION_DENIED;
6917        }
6918        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6919    }
6920
6921    /**
6922     * Binder IPC calls go through the public entry point.
6923     * This can be called with or without the global lock held.
6924     */
6925    int checkCallingPermission(String permission) {
6926        return checkPermission(permission,
6927                Binder.getCallingPid(),
6928                UserHandle.getAppId(Binder.getCallingUid()));
6929    }
6930
6931    /**
6932     * This can be called with or without the global lock held.
6933     */
6934    void enforceCallingPermission(String permission, String func) {
6935        if (checkCallingPermission(permission)
6936                == PackageManager.PERMISSION_GRANTED) {
6937            return;
6938        }
6939
6940        String msg = "Permission Denial: " + func + " from pid="
6941                + Binder.getCallingPid()
6942                + ", uid=" + Binder.getCallingUid()
6943                + " requires " + permission;
6944        Slog.w(TAG, msg);
6945        throw new SecurityException(msg);
6946    }
6947
6948    /**
6949     * Determine if UID is holding permissions required to access {@link Uri} in
6950     * the given {@link ProviderInfo}. Final permission checking is always done
6951     * in {@link ContentProvider}.
6952     */
6953    private final boolean checkHoldingPermissionsLocked(
6954            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6955        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6956                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6957        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6958            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6959                    != PERMISSION_GRANTED) {
6960                return false;
6961            }
6962        }
6963        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6964    }
6965
6966    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6967            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6968        if (pi.applicationInfo.uid == uid) {
6969            return true;
6970        } else if (!pi.exported) {
6971            return false;
6972        }
6973
6974        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6975        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6976        try {
6977            // check if target holds top-level <provider> permissions
6978            if (!readMet && pi.readPermission != null && considerUidPermissions
6979                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6980                readMet = true;
6981            }
6982            if (!writeMet && pi.writePermission != null && considerUidPermissions
6983                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6984                writeMet = true;
6985            }
6986
6987            // track if unprotected read/write is allowed; any denied
6988            // <path-permission> below removes this ability
6989            boolean allowDefaultRead = pi.readPermission == null;
6990            boolean allowDefaultWrite = pi.writePermission == null;
6991
6992            // check if target holds any <path-permission> that match uri
6993            final PathPermission[] pps = pi.pathPermissions;
6994            if (pps != null) {
6995                final String path = grantUri.uri.getPath();
6996                int i = pps.length;
6997                while (i > 0 && (!readMet || !writeMet)) {
6998                    i--;
6999                    PathPermission pp = pps[i];
7000                    if (pp.match(path)) {
7001                        if (!readMet) {
7002                            final String pprperm = pp.getReadPermission();
7003                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7004                                    + pprperm + " for " + pp.getPath()
7005                                    + ": match=" + pp.match(path)
7006                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7007                            if (pprperm != null) {
7008                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7009                                        == PERMISSION_GRANTED) {
7010                                    readMet = true;
7011                                } else {
7012                                    allowDefaultRead = false;
7013                                }
7014                            }
7015                        }
7016                        if (!writeMet) {
7017                            final String ppwperm = pp.getWritePermission();
7018                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7019                                    + ppwperm + " for " + pp.getPath()
7020                                    + ": match=" + pp.match(path)
7021                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7022                            if (ppwperm != null) {
7023                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7024                                        == PERMISSION_GRANTED) {
7025                                    writeMet = true;
7026                                } else {
7027                                    allowDefaultWrite = false;
7028                                }
7029                            }
7030                        }
7031                    }
7032                }
7033            }
7034
7035            // grant unprotected <provider> read/write, if not blocked by
7036            // <path-permission> above
7037            if (allowDefaultRead) readMet = true;
7038            if (allowDefaultWrite) writeMet = true;
7039
7040        } catch (RemoteException e) {
7041            return false;
7042        }
7043
7044        return readMet && writeMet;
7045    }
7046
7047    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7048        ProviderInfo pi = null;
7049        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7050        if (cpr != null) {
7051            pi = cpr.info;
7052        } else {
7053            try {
7054                pi = AppGlobals.getPackageManager().resolveContentProvider(
7055                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7056            } catch (RemoteException ex) {
7057            }
7058        }
7059        return pi;
7060    }
7061
7062    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7063        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7064        if (targetUris != null) {
7065            return targetUris.get(grantUri);
7066        }
7067        return null;
7068    }
7069
7070    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7071            String targetPkg, int targetUid, GrantUri grantUri) {
7072        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7073        if (targetUris == null) {
7074            targetUris = Maps.newArrayMap();
7075            mGrantedUriPermissions.put(targetUid, targetUris);
7076        }
7077
7078        UriPermission perm = targetUris.get(grantUri);
7079        if (perm == null) {
7080            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7081            targetUris.put(grantUri, perm);
7082        }
7083
7084        return perm;
7085    }
7086
7087    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7088            final int modeFlags) {
7089        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7090        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7091                : UriPermission.STRENGTH_OWNED;
7092
7093        // Root gets to do everything.
7094        if (uid == 0) {
7095            return true;
7096        }
7097
7098        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7099        if (perms == null) return false;
7100
7101        // First look for exact match
7102        final UriPermission exactPerm = perms.get(grantUri);
7103        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7104            return true;
7105        }
7106
7107        // No exact match, look for prefixes
7108        final int N = perms.size();
7109        for (int i = 0; i < N; i++) {
7110            final UriPermission perm = perms.valueAt(i);
7111            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7112                    && perm.getStrength(modeFlags) >= minStrength) {
7113                return true;
7114            }
7115        }
7116
7117        return false;
7118    }
7119
7120    /**
7121     * @param uri This uri must NOT contain an embedded userId.
7122     * @param userId The userId in which the uri is to be resolved.
7123     */
7124    @Override
7125    public int checkUriPermission(Uri uri, int pid, int uid,
7126            final int modeFlags, int userId) {
7127        enforceNotIsolatedCaller("checkUriPermission");
7128
7129        // Another redirected-binder-call permissions check as in
7130        // {@link checkComponentPermission}.
7131        Identity tlsIdentity = sCallerIdentity.get();
7132        if (tlsIdentity != null) {
7133            uid = tlsIdentity.uid;
7134            pid = tlsIdentity.pid;
7135        }
7136
7137        // Our own process gets to do everything.
7138        if (pid == MY_PID) {
7139            return PackageManager.PERMISSION_GRANTED;
7140        }
7141        synchronized (this) {
7142            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7143                    ? PackageManager.PERMISSION_GRANTED
7144                    : PackageManager.PERMISSION_DENIED;
7145        }
7146    }
7147
7148    /**
7149     * Check if the targetPkg can be granted permission to access uri by
7150     * the callingUid using the given modeFlags.  Throws a security exception
7151     * if callingUid is not allowed to do this.  Returns the uid of the target
7152     * if the URI permission grant should be performed; returns -1 if it is not
7153     * needed (for example targetPkg already has permission to access the URI).
7154     * If you already know the uid of the target, you can supply it in
7155     * lastTargetUid else set that to -1.
7156     */
7157    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7158            final int modeFlags, int lastTargetUid) {
7159        if (!Intent.isAccessUriMode(modeFlags)) {
7160            return -1;
7161        }
7162
7163        if (targetPkg != null) {
7164            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7165                    "Checking grant " + targetPkg + " permission to " + grantUri);
7166        }
7167
7168        final IPackageManager pm = AppGlobals.getPackageManager();
7169
7170        // If this is not a content: uri, we can't do anything with it.
7171        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7172            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7173                    "Can't grant URI permission for non-content URI: " + grantUri);
7174            return -1;
7175        }
7176
7177        final String authority = grantUri.uri.getAuthority();
7178        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7179        if (pi == null) {
7180            Slog.w(TAG, "No content provider found for permission check: " +
7181                    grantUri.uri.toSafeString());
7182            return -1;
7183        }
7184
7185        int targetUid = lastTargetUid;
7186        if (targetUid < 0 && targetPkg != null) {
7187            try {
7188                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7189                if (targetUid < 0) {
7190                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7191                            "Can't grant URI permission no uid for: " + targetPkg);
7192                    return -1;
7193                }
7194            } catch (RemoteException ex) {
7195                return -1;
7196            }
7197        }
7198
7199        if (targetUid >= 0) {
7200            // First...  does the target actually need this permission?
7201            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7202                // No need to grant the target this permission.
7203                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7204                        "Target " + targetPkg + " already has full permission to " + grantUri);
7205                return -1;
7206            }
7207        } else {
7208            // First...  there is no target package, so can anyone access it?
7209            boolean allowed = pi.exported;
7210            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7211                if (pi.readPermission != null) {
7212                    allowed = false;
7213                }
7214            }
7215            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7216                if (pi.writePermission != null) {
7217                    allowed = false;
7218                }
7219            }
7220            if (allowed) {
7221                return -1;
7222            }
7223        }
7224
7225        /* There is a special cross user grant if:
7226         * - The target is on another user.
7227         * - Apps on the current user can access the uri without any uid permissions.
7228         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7229         * grant uri permissions.
7230         */
7231        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7232                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7233                modeFlags, false /*without considering the uid permissions*/);
7234
7235        // Second...  is the provider allowing granting of URI permissions?
7236        if (!specialCrossUserGrant) {
7237            if (!pi.grantUriPermissions) {
7238                throw new SecurityException("Provider " + pi.packageName
7239                        + "/" + pi.name
7240                        + " does not allow granting of Uri permissions (uri "
7241                        + grantUri + ")");
7242            }
7243            if (pi.uriPermissionPatterns != null) {
7244                final int N = pi.uriPermissionPatterns.length;
7245                boolean allowed = false;
7246                for (int i=0; i<N; i++) {
7247                    if (pi.uriPermissionPatterns[i] != null
7248                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7249                        allowed = true;
7250                        break;
7251                    }
7252                }
7253                if (!allowed) {
7254                    throw new SecurityException("Provider " + pi.packageName
7255                            + "/" + pi.name
7256                            + " does not allow granting of permission to path of Uri "
7257                            + grantUri);
7258                }
7259            }
7260        }
7261
7262        // Third...  does the caller itself have permission to access
7263        // this uri?
7264        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7265            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7266                // Require they hold a strong enough Uri permission
7267                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7268                    throw new SecurityException("Uid " + callingUid
7269                            + " does not have permission to uri " + grantUri);
7270                }
7271            }
7272        }
7273        return targetUid;
7274    }
7275
7276    /**
7277     * @param uri This uri must NOT contain an embedded userId.
7278     * @param userId The userId in which the uri is to be resolved.
7279     */
7280    @Override
7281    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7282            final int modeFlags, int userId) {
7283        enforceNotIsolatedCaller("checkGrantUriPermission");
7284        synchronized(this) {
7285            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7286                    new GrantUri(userId, uri, false), modeFlags, -1);
7287        }
7288    }
7289
7290    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7291            final int modeFlags, UriPermissionOwner owner) {
7292        if (!Intent.isAccessUriMode(modeFlags)) {
7293            return;
7294        }
7295
7296        // So here we are: the caller has the assumed permission
7297        // to the uri, and the target doesn't.  Let's now give this to
7298        // the target.
7299
7300        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7301                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7302
7303        final String authority = grantUri.uri.getAuthority();
7304        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7305        if (pi == null) {
7306            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7307            return;
7308        }
7309
7310        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7311            grantUri.prefix = true;
7312        }
7313        final UriPermission perm = findOrCreateUriPermissionLocked(
7314                pi.packageName, targetPkg, targetUid, grantUri);
7315        perm.grantModes(modeFlags, owner);
7316    }
7317
7318    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7319            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7320        if (targetPkg == null) {
7321            throw new NullPointerException("targetPkg");
7322        }
7323        int targetUid;
7324        final IPackageManager pm = AppGlobals.getPackageManager();
7325        try {
7326            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7327        } catch (RemoteException ex) {
7328            return;
7329        }
7330
7331        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7332                targetUid);
7333        if (targetUid < 0) {
7334            return;
7335        }
7336
7337        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7338                owner);
7339    }
7340
7341    static class NeededUriGrants extends ArrayList<GrantUri> {
7342        final String targetPkg;
7343        final int targetUid;
7344        final int flags;
7345
7346        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7347            this.targetPkg = targetPkg;
7348            this.targetUid = targetUid;
7349            this.flags = flags;
7350        }
7351    }
7352
7353    /**
7354     * Like checkGrantUriPermissionLocked, but takes an Intent.
7355     */
7356    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7357            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7358        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7359                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7360                + " clip=" + (intent != null ? intent.getClipData() : null)
7361                + " from " + intent + "; flags=0x"
7362                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7363
7364        if (targetPkg == null) {
7365            throw new NullPointerException("targetPkg");
7366        }
7367
7368        if (intent == null) {
7369            return null;
7370        }
7371        Uri data = intent.getData();
7372        ClipData clip = intent.getClipData();
7373        if (data == null && clip == null) {
7374            return null;
7375        }
7376        // Default userId for uris in the intent (if they don't specify it themselves)
7377        int contentUserHint = intent.getContentUserHint();
7378        if (contentUserHint == UserHandle.USER_CURRENT) {
7379            contentUserHint = UserHandle.getUserId(callingUid);
7380        }
7381        final IPackageManager pm = AppGlobals.getPackageManager();
7382        int targetUid;
7383        if (needed != null) {
7384            targetUid = needed.targetUid;
7385        } else {
7386            try {
7387                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7388            } catch (RemoteException ex) {
7389                return null;
7390            }
7391            if (targetUid < 0) {
7392                if (DEBUG_URI_PERMISSION) {
7393                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7394                            + " on user " + targetUserId);
7395                }
7396                return null;
7397            }
7398        }
7399        if (data != null) {
7400            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7401            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7402                    targetUid);
7403            if (targetUid > 0) {
7404                if (needed == null) {
7405                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7406                }
7407                needed.add(grantUri);
7408            }
7409        }
7410        if (clip != null) {
7411            for (int i=0; i<clip.getItemCount(); i++) {
7412                Uri uri = clip.getItemAt(i).getUri();
7413                if (uri != null) {
7414                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7415                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7416                            targetUid);
7417                    if (targetUid > 0) {
7418                        if (needed == null) {
7419                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7420                        }
7421                        needed.add(grantUri);
7422                    }
7423                } else {
7424                    Intent clipIntent = clip.getItemAt(i).getIntent();
7425                    if (clipIntent != null) {
7426                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7427                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7428                        if (newNeeded != null) {
7429                            needed = newNeeded;
7430                        }
7431                    }
7432                }
7433            }
7434        }
7435
7436        return needed;
7437    }
7438
7439    /**
7440     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7441     */
7442    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7443            UriPermissionOwner owner) {
7444        if (needed != null) {
7445            for (int i=0; i<needed.size(); i++) {
7446                GrantUri grantUri = needed.get(i);
7447                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7448                        grantUri, needed.flags, owner);
7449            }
7450        }
7451    }
7452
7453    void grantUriPermissionFromIntentLocked(int callingUid,
7454            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7455        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7456                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7457        if (needed == null) {
7458            return;
7459        }
7460
7461        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7462    }
7463
7464    /**
7465     * @param uri This uri must NOT contain an embedded userId.
7466     * @param userId The userId in which the uri is to be resolved.
7467     */
7468    @Override
7469    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7470            final int modeFlags, int userId) {
7471        enforceNotIsolatedCaller("grantUriPermission");
7472        GrantUri grantUri = new GrantUri(userId, uri, false);
7473        synchronized(this) {
7474            final ProcessRecord r = getRecordForAppLocked(caller);
7475            if (r == null) {
7476                throw new SecurityException("Unable to find app for caller "
7477                        + caller
7478                        + " when granting permission to uri " + grantUri);
7479            }
7480            if (targetPkg == null) {
7481                throw new IllegalArgumentException("null target");
7482            }
7483            if (grantUri == null) {
7484                throw new IllegalArgumentException("null uri");
7485            }
7486
7487            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7488                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7489                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7490                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7491
7492            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7493                    UserHandle.getUserId(r.uid));
7494        }
7495    }
7496
7497    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7498        if (perm.modeFlags == 0) {
7499            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7500                    perm.targetUid);
7501            if (perms != null) {
7502                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7503                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7504
7505                perms.remove(perm.uri);
7506                if (perms.isEmpty()) {
7507                    mGrantedUriPermissions.remove(perm.targetUid);
7508                }
7509            }
7510        }
7511    }
7512
7513    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7514        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7515
7516        final IPackageManager pm = AppGlobals.getPackageManager();
7517        final String authority = grantUri.uri.getAuthority();
7518        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7519        if (pi == null) {
7520            Slog.w(TAG, "No content provider found for permission revoke: "
7521                    + grantUri.toSafeString());
7522            return;
7523        }
7524
7525        // Does the caller have this permission on the URI?
7526        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7527            // If they don't have direct access to the URI, then revoke any
7528            // ownerless URI permissions that have been granted to them.
7529            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7530            if (perms != null) {
7531                boolean persistChanged = false;
7532                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7533                    final UriPermission perm = it.next();
7534                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7535                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7536                        if (DEBUG_URI_PERMISSION)
7537                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7538                                    " permission to " + perm.uri);
7539                        persistChanged |= perm.revokeModes(
7540                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7541                        if (perm.modeFlags == 0) {
7542                            it.remove();
7543                        }
7544                    }
7545                }
7546                if (perms.isEmpty()) {
7547                    mGrantedUriPermissions.remove(callingUid);
7548                }
7549                if (persistChanged) {
7550                    schedulePersistUriGrants();
7551                }
7552            }
7553            return;
7554        }
7555
7556        boolean persistChanged = false;
7557
7558        // Go through all of the permissions and remove any that match.
7559        int N = mGrantedUriPermissions.size();
7560        for (int i = 0; i < N; i++) {
7561            final int targetUid = mGrantedUriPermissions.keyAt(i);
7562            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7563
7564            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7565                final UriPermission perm = it.next();
7566                if (perm.uri.sourceUserId == grantUri.sourceUserId
7567                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7568                    if (DEBUG_URI_PERMISSION)
7569                        Slog.v(TAG,
7570                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7571                    persistChanged |= perm.revokeModes(
7572                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7573                    if (perm.modeFlags == 0) {
7574                        it.remove();
7575                    }
7576                }
7577            }
7578
7579            if (perms.isEmpty()) {
7580                mGrantedUriPermissions.remove(targetUid);
7581                N--;
7582                i--;
7583            }
7584        }
7585
7586        if (persistChanged) {
7587            schedulePersistUriGrants();
7588        }
7589    }
7590
7591    /**
7592     * @param uri This uri must NOT contain an embedded userId.
7593     * @param userId The userId in which the uri is to be resolved.
7594     */
7595    @Override
7596    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7597            int userId) {
7598        enforceNotIsolatedCaller("revokeUriPermission");
7599        synchronized(this) {
7600            final ProcessRecord r = getRecordForAppLocked(caller);
7601            if (r == null) {
7602                throw new SecurityException("Unable to find app for caller "
7603                        + caller
7604                        + " when revoking permission to uri " + uri);
7605            }
7606            if (uri == null) {
7607                Slog.w(TAG, "revokeUriPermission: null uri");
7608                return;
7609            }
7610
7611            if (!Intent.isAccessUriMode(modeFlags)) {
7612                return;
7613            }
7614
7615            final IPackageManager pm = AppGlobals.getPackageManager();
7616            final String authority = uri.getAuthority();
7617            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7618            if (pi == null) {
7619                Slog.w(TAG, "No content provider found for permission revoke: "
7620                        + uri.toSafeString());
7621                return;
7622            }
7623
7624            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7625        }
7626    }
7627
7628    /**
7629     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7630     * given package.
7631     *
7632     * @param packageName Package name to match, or {@code null} to apply to all
7633     *            packages.
7634     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7635     *            to all users.
7636     * @param persistable If persistable grants should be removed.
7637     */
7638    private void removeUriPermissionsForPackageLocked(
7639            String packageName, int userHandle, boolean persistable) {
7640        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7641            throw new IllegalArgumentException("Must narrow by either package or user");
7642        }
7643
7644        boolean persistChanged = false;
7645
7646        int N = mGrantedUriPermissions.size();
7647        for (int i = 0; i < N; i++) {
7648            final int targetUid = mGrantedUriPermissions.keyAt(i);
7649            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7650
7651            // Only inspect grants matching user
7652            if (userHandle == UserHandle.USER_ALL
7653                    || userHandle == UserHandle.getUserId(targetUid)) {
7654                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7655                    final UriPermission perm = it.next();
7656
7657                    // Only inspect grants matching package
7658                    if (packageName == null || perm.sourcePkg.equals(packageName)
7659                            || perm.targetPkg.equals(packageName)) {
7660                        persistChanged |= perm.revokeModes(persistable
7661                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7662
7663                        // Only remove when no modes remain; any persisted grants
7664                        // will keep this alive.
7665                        if (perm.modeFlags == 0) {
7666                            it.remove();
7667                        }
7668                    }
7669                }
7670
7671                if (perms.isEmpty()) {
7672                    mGrantedUriPermissions.remove(targetUid);
7673                    N--;
7674                    i--;
7675                }
7676            }
7677        }
7678
7679        if (persistChanged) {
7680            schedulePersistUriGrants();
7681        }
7682    }
7683
7684    @Override
7685    public IBinder newUriPermissionOwner(String name) {
7686        enforceNotIsolatedCaller("newUriPermissionOwner");
7687        synchronized(this) {
7688            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7689            return owner.getExternalTokenLocked();
7690        }
7691    }
7692
7693    /**
7694     * @param uri This uri must NOT contain an embedded userId.
7695     * @param sourceUserId The userId in which the uri is to be resolved.
7696     * @param targetUserId The userId of the app that receives the grant.
7697     */
7698    @Override
7699    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7700            final int modeFlags, int sourceUserId, int targetUserId) {
7701        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7702                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7703        synchronized(this) {
7704            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7705            if (owner == null) {
7706                throw new IllegalArgumentException("Unknown owner: " + token);
7707            }
7708            if (fromUid != Binder.getCallingUid()) {
7709                if (Binder.getCallingUid() != Process.myUid()) {
7710                    // Only system code can grant URI permissions on behalf
7711                    // of other users.
7712                    throw new SecurityException("nice try");
7713                }
7714            }
7715            if (targetPkg == null) {
7716                throw new IllegalArgumentException("null target");
7717            }
7718            if (uri == null) {
7719                throw new IllegalArgumentException("null uri");
7720            }
7721
7722            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7723                    modeFlags, owner, targetUserId);
7724        }
7725    }
7726
7727    /**
7728     * @param uri This uri must NOT contain an embedded userId.
7729     * @param userId The userId in which the uri is to be resolved.
7730     */
7731    @Override
7732    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7733        synchronized(this) {
7734            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7735            if (owner == null) {
7736                throw new IllegalArgumentException("Unknown owner: " + token);
7737            }
7738
7739            if (uri == null) {
7740                owner.removeUriPermissionsLocked(mode);
7741            } else {
7742                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7743            }
7744        }
7745    }
7746
7747    private void schedulePersistUriGrants() {
7748        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7749            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7750                    10 * DateUtils.SECOND_IN_MILLIS);
7751        }
7752    }
7753
7754    private void writeGrantedUriPermissions() {
7755        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7756
7757        // Snapshot permissions so we can persist without lock
7758        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7759        synchronized (this) {
7760            final int size = mGrantedUriPermissions.size();
7761            for (int i = 0; i < size; i++) {
7762                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7763                for (UriPermission perm : perms.values()) {
7764                    if (perm.persistedModeFlags != 0) {
7765                        persist.add(perm.snapshot());
7766                    }
7767                }
7768            }
7769        }
7770
7771        FileOutputStream fos = null;
7772        try {
7773            fos = mGrantFile.startWrite();
7774
7775            XmlSerializer out = new FastXmlSerializer();
7776            out.setOutput(fos, "utf-8");
7777            out.startDocument(null, true);
7778            out.startTag(null, TAG_URI_GRANTS);
7779            for (UriPermission.Snapshot perm : persist) {
7780                out.startTag(null, TAG_URI_GRANT);
7781                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7782                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7783                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7784                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7785                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7786                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7787                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7788                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7789                out.endTag(null, TAG_URI_GRANT);
7790            }
7791            out.endTag(null, TAG_URI_GRANTS);
7792            out.endDocument();
7793
7794            mGrantFile.finishWrite(fos);
7795        } catch (IOException e) {
7796            if (fos != null) {
7797                mGrantFile.failWrite(fos);
7798            }
7799        }
7800    }
7801
7802    private void readGrantedUriPermissionsLocked() {
7803        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7804
7805        final long now = System.currentTimeMillis();
7806
7807        FileInputStream fis = null;
7808        try {
7809            fis = mGrantFile.openRead();
7810            final XmlPullParser in = Xml.newPullParser();
7811            in.setInput(fis, null);
7812
7813            int type;
7814            while ((type = in.next()) != END_DOCUMENT) {
7815                final String tag = in.getName();
7816                if (type == START_TAG) {
7817                    if (TAG_URI_GRANT.equals(tag)) {
7818                        final int sourceUserId;
7819                        final int targetUserId;
7820                        final int userHandle = readIntAttribute(in,
7821                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7822                        if (userHandle != UserHandle.USER_NULL) {
7823                            // For backwards compatibility.
7824                            sourceUserId = userHandle;
7825                            targetUserId = userHandle;
7826                        } else {
7827                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7828                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7829                        }
7830                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7831                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7832                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7833                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7834                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7835                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7836
7837                        // Sanity check that provider still belongs to source package
7838                        final ProviderInfo pi = getProviderInfoLocked(
7839                                uri.getAuthority(), sourceUserId);
7840                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7841                            int targetUid = -1;
7842                            try {
7843                                targetUid = AppGlobals.getPackageManager()
7844                                        .getPackageUid(targetPkg, targetUserId);
7845                            } catch (RemoteException e) {
7846                            }
7847                            if (targetUid != -1) {
7848                                final UriPermission perm = findOrCreateUriPermissionLocked(
7849                                        sourcePkg, targetPkg, targetUid,
7850                                        new GrantUri(sourceUserId, uri, prefix));
7851                                perm.initPersistedModes(modeFlags, createdTime);
7852                            }
7853                        } else {
7854                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7855                                    + " but instead found " + pi);
7856                        }
7857                    }
7858                }
7859            }
7860        } catch (FileNotFoundException e) {
7861            // Missing grants is okay
7862        } catch (IOException e) {
7863            Log.wtf(TAG, "Failed reading Uri grants", e);
7864        } catch (XmlPullParserException e) {
7865            Log.wtf(TAG, "Failed reading Uri grants", e);
7866        } finally {
7867            IoUtils.closeQuietly(fis);
7868        }
7869    }
7870
7871    /**
7872     * @param uri This uri must NOT contain an embedded userId.
7873     * @param userId The userId in which the uri is to be resolved.
7874     */
7875    @Override
7876    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7877        enforceNotIsolatedCaller("takePersistableUriPermission");
7878
7879        Preconditions.checkFlagsArgument(modeFlags,
7880                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7881
7882        synchronized (this) {
7883            final int callingUid = Binder.getCallingUid();
7884            boolean persistChanged = false;
7885            GrantUri grantUri = new GrantUri(userId, uri, false);
7886
7887            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7888                    new GrantUri(userId, uri, false));
7889            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7890                    new GrantUri(userId, uri, true));
7891
7892            final boolean exactValid = (exactPerm != null)
7893                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7894            final boolean prefixValid = (prefixPerm != null)
7895                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7896
7897            if (!(exactValid || prefixValid)) {
7898                throw new SecurityException("No persistable permission grants found for UID "
7899                        + callingUid + " and Uri " + grantUri.toSafeString());
7900            }
7901
7902            if (exactValid) {
7903                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7904            }
7905            if (prefixValid) {
7906                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7907            }
7908
7909            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7910
7911            if (persistChanged) {
7912                schedulePersistUriGrants();
7913            }
7914        }
7915    }
7916
7917    /**
7918     * @param uri This uri must NOT contain an embedded userId.
7919     * @param userId The userId in which the uri is to be resolved.
7920     */
7921    @Override
7922    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7923        enforceNotIsolatedCaller("releasePersistableUriPermission");
7924
7925        Preconditions.checkFlagsArgument(modeFlags,
7926                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7927
7928        synchronized (this) {
7929            final int callingUid = Binder.getCallingUid();
7930            boolean persistChanged = false;
7931
7932            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7933                    new GrantUri(userId, uri, false));
7934            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7935                    new GrantUri(userId, uri, true));
7936            if (exactPerm == null && prefixPerm == null) {
7937                throw new SecurityException("No permission grants found for UID " + callingUid
7938                        + " and Uri " + uri.toSafeString());
7939            }
7940
7941            if (exactPerm != null) {
7942                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7943                removeUriPermissionIfNeededLocked(exactPerm);
7944            }
7945            if (prefixPerm != null) {
7946                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7947                removeUriPermissionIfNeededLocked(prefixPerm);
7948            }
7949
7950            if (persistChanged) {
7951                schedulePersistUriGrants();
7952            }
7953        }
7954    }
7955
7956    /**
7957     * Prune any older {@link UriPermission} for the given UID until outstanding
7958     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7959     *
7960     * @return if any mutations occured that require persisting.
7961     */
7962    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7963        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7964        if (perms == null) return false;
7965        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7966
7967        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7968        for (UriPermission perm : perms.values()) {
7969            if (perm.persistedModeFlags != 0) {
7970                persisted.add(perm);
7971            }
7972        }
7973
7974        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7975        if (trimCount <= 0) return false;
7976
7977        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7978        for (int i = 0; i < trimCount; i++) {
7979            final UriPermission perm = persisted.get(i);
7980
7981            if (DEBUG_URI_PERMISSION) {
7982                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7983            }
7984
7985            perm.releasePersistableModes(~0);
7986            removeUriPermissionIfNeededLocked(perm);
7987        }
7988
7989        return true;
7990    }
7991
7992    @Override
7993    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7994            String packageName, boolean incoming) {
7995        enforceNotIsolatedCaller("getPersistedUriPermissions");
7996        Preconditions.checkNotNull(packageName, "packageName");
7997
7998        final int callingUid = Binder.getCallingUid();
7999        final IPackageManager pm = AppGlobals.getPackageManager();
8000        try {
8001            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8002            if (packageUid != callingUid) {
8003                throw new SecurityException(
8004                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8005            }
8006        } catch (RemoteException e) {
8007            throw new SecurityException("Failed to verify package name ownership");
8008        }
8009
8010        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8011        synchronized (this) {
8012            if (incoming) {
8013                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8014                        callingUid);
8015                if (perms == null) {
8016                    Slog.w(TAG, "No permission grants found for " + packageName);
8017                } else {
8018                    for (UriPermission perm : perms.values()) {
8019                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8020                            result.add(perm.buildPersistedPublicApiObject());
8021                        }
8022                    }
8023                }
8024            } else {
8025                final int size = mGrantedUriPermissions.size();
8026                for (int i = 0; i < size; i++) {
8027                    final ArrayMap<GrantUri, UriPermission> perms =
8028                            mGrantedUriPermissions.valueAt(i);
8029                    for (UriPermission perm : perms.values()) {
8030                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8031                            result.add(perm.buildPersistedPublicApiObject());
8032                        }
8033                    }
8034                }
8035            }
8036        }
8037        return new ParceledListSlice<android.content.UriPermission>(result);
8038    }
8039
8040    @Override
8041    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8042        synchronized (this) {
8043            ProcessRecord app =
8044                who != null ? getRecordForAppLocked(who) : null;
8045            if (app == null) return;
8046
8047            Message msg = Message.obtain();
8048            msg.what = WAIT_FOR_DEBUGGER_MSG;
8049            msg.obj = app;
8050            msg.arg1 = waiting ? 1 : 0;
8051            mHandler.sendMessage(msg);
8052        }
8053    }
8054
8055    @Override
8056    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8057        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8058        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8059        outInfo.availMem = Process.getFreeMemory();
8060        outInfo.totalMem = Process.getTotalMemory();
8061        outInfo.threshold = homeAppMem;
8062        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8063        outInfo.hiddenAppThreshold = cachedAppMem;
8064        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8065                ProcessList.SERVICE_ADJ);
8066        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8067                ProcessList.VISIBLE_APP_ADJ);
8068        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8069                ProcessList.FOREGROUND_APP_ADJ);
8070    }
8071
8072    // =========================================================
8073    // TASK MANAGEMENT
8074    // =========================================================
8075
8076    @Override
8077    public List<IAppTask> getAppTasks(String callingPackage) {
8078        int callingUid = Binder.getCallingUid();
8079        long ident = Binder.clearCallingIdentity();
8080
8081        synchronized(this) {
8082            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8083            try {
8084                if (localLOGV) Slog.v(TAG, "getAppTasks");
8085
8086                final int N = mRecentTasks.size();
8087                for (int i = 0; i < N; i++) {
8088                    TaskRecord tr = mRecentTasks.get(i);
8089                    // Skip tasks that do not match the caller.  We don't need to verify
8090                    // callingPackage, because we are also limiting to callingUid and know
8091                    // that will limit to the correct security sandbox.
8092                    if (tr.effectiveUid != callingUid) {
8093                        continue;
8094                    }
8095                    Intent intent = tr.getBaseIntent();
8096                    if (intent == null ||
8097                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8098                        continue;
8099                    }
8100                    ActivityManager.RecentTaskInfo taskInfo =
8101                            createRecentTaskInfoFromTaskRecord(tr);
8102                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8103                    list.add(taskImpl);
8104                }
8105            } finally {
8106                Binder.restoreCallingIdentity(ident);
8107            }
8108            return list;
8109        }
8110    }
8111
8112    @Override
8113    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8114        final int callingUid = Binder.getCallingUid();
8115        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8116
8117        synchronized(this) {
8118            if (localLOGV) Slog.v(
8119                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8120
8121            final boolean allowed = checkCallingPermission(
8122                    android.Manifest.permission.GET_TASKS)
8123                    == PackageManager.PERMISSION_GRANTED;
8124            if (!allowed) {
8125                Slog.w(TAG, "getTasks: caller " + callingUid
8126                        + " does not hold GET_TASKS; limiting output");
8127            }
8128
8129            // TODO: Improve with MRU list from all ActivityStacks.
8130            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8131        }
8132
8133        return list;
8134    }
8135
8136    TaskRecord getMostRecentTask() {
8137        return mRecentTasks.get(0);
8138    }
8139
8140    /**
8141     * Creates a new RecentTaskInfo from a TaskRecord.
8142     */
8143    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8144        // Update the task description to reflect any changes in the task stack
8145        tr.updateTaskDescription();
8146
8147        // Compose the recent task info
8148        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8149        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8150        rti.persistentId = tr.taskId;
8151        rti.baseIntent = new Intent(tr.getBaseIntent());
8152        rti.origActivity = tr.origActivity;
8153        rti.description = tr.lastDescription;
8154        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8155        rti.userId = tr.userId;
8156        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8157        rti.firstActiveTime = tr.firstActiveTime;
8158        rti.lastActiveTime = tr.lastActiveTime;
8159        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8160        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8161        return rti;
8162    }
8163
8164    @Override
8165    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8166        final int callingUid = Binder.getCallingUid();
8167        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8168                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8169
8170        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8171        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8172        synchronized (this) {
8173            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8174                    == PackageManager.PERMISSION_GRANTED;
8175            if (!allowed) {
8176                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8177                        + " does not hold GET_TASKS; limiting output");
8178            }
8179            final boolean detailed = checkCallingPermission(
8180                    android.Manifest.permission.GET_DETAILED_TASKS)
8181                    == PackageManager.PERMISSION_GRANTED;
8182
8183            final int N = mRecentTasks.size();
8184            ArrayList<ActivityManager.RecentTaskInfo> res
8185                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8186                            maxNum < N ? maxNum : N);
8187
8188            final Set<Integer> includedUsers;
8189            if (includeProfiles) {
8190                includedUsers = getProfileIdsLocked(userId);
8191            } else {
8192                includedUsers = new HashSet<Integer>();
8193            }
8194            includedUsers.add(Integer.valueOf(userId));
8195
8196            for (int i=0; i<N && maxNum > 0; i++) {
8197                TaskRecord tr = mRecentTasks.get(i);
8198                // Only add calling user or related users recent tasks
8199                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8200                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8201                    continue;
8202                }
8203
8204                // Return the entry if desired by the caller.  We always return
8205                // the first entry, because callers always expect this to be the
8206                // foreground app.  We may filter others if the caller has
8207                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8208                // we should exclude the entry.
8209
8210                if (i == 0
8211                        || withExcluded
8212                        || (tr.intent == null)
8213                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8214                                == 0)) {
8215                    if (!allowed) {
8216                        // If the caller doesn't have the GET_TASKS permission, then only
8217                        // allow them to see a small subset of tasks -- their own and home.
8218                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8219                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8220                            continue;
8221                        }
8222                    }
8223                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8224                        if (tr.stack != null && tr.stack.isHomeStack()) {
8225                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8226                            continue;
8227                        }
8228                    }
8229                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8230                        // Don't include auto remove tasks that are finished or finishing.
8231                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8232                                + tr);
8233                        continue;
8234                    }
8235                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8236                            && !tr.isAvailable) {
8237                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8238                        continue;
8239                    }
8240
8241                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8242                    if (!detailed) {
8243                        rti.baseIntent.replaceExtras((Bundle)null);
8244                    }
8245
8246                    res.add(rti);
8247                    maxNum--;
8248                }
8249            }
8250            return res;
8251        }
8252    }
8253
8254    private TaskRecord recentTaskForIdLocked(int id) {
8255        final int N = mRecentTasks.size();
8256            for (int i=0; i<N; i++) {
8257                TaskRecord tr = mRecentTasks.get(i);
8258                if (tr.taskId == id) {
8259                    return tr;
8260                }
8261            }
8262            return null;
8263    }
8264
8265    @Override
8266    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8267        synchronized (this) {
8268            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8269                    "getTaskThumbnail()");
8270            TaskRecord tr = recentTaskForIdLocked(id);
8271            if (tr != null) {
8272                return tr.getTaskThumbnailLocked();
8273            }
8274        }
8275        return null;
8276    }
8277
8278    @Override
8279    public int addAppTask(IBinder activityToken, Intent intent,
8280            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8281        final int callingUid = Binder.getCallingUid();
8282        final long callingIdent = Binder.clearCallingIdentity();
8283
8284        try {
8285            synchronized (this) {
8286                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8287                if (r == null) {
8288                    throw new IllegalArgumentException("Activity does not exist; token="
8289                            + activityToken);
8290                }
8291                ComponentName comp = intent.getComponent();
8292                if (comp == null) {
8293                    throw new IllegalArgumentException("Intent " + intent
8294                            + " must specify explicit component");
8295                }
8296                if (thumbnail.getWidth() != mThumbnailWidth
8297                        || thumbnail.getHeight() != mThumbnailHeight) {
8298                    throw new IllegalArgumentException("Bad thumbnail size: got "
8299                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8300                            + mThumbnailWidth + "x" + mThumbnailHeight);
8301                }
8302                if (intent.getSelector() != null) {
8303                    intent.setSelector(null);
8304                }
8305                if (intent.getSourceBounds() != null) {
8306                    intent.setSourceBounds(null);
8307                }
8308                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8309                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8310                        // The caller has added this as an auto-remove task...  that makes no
8311                        // sense, so turn off auto-remove.
8312                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8313                    }
8314                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8315                    // Must be a new task.
8316                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8317                }
8318                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8319                    mLastAddedTaskActivity = null;
8320                }
8321                ActivityInfo ainfo = mLastAddedTaskActivity;
8322                if (ainfo == null) {
8323                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8324                            comp, 0, UserHandle.getUserId(callingUid));
8325                    if (ainfo.applicationInfo.uid != callingUid) {
8326                        throw new SecurityException(
8327                                "Can't add task for another application: target uid="
8328                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8329                    }
8330                }
8331
8332                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8333                        intent, description);
8334
8335                int trimIdx = trimRecentsForTask(task, false);
8336                if (trimIdx >= 0) {
8337                    // If this would have caused a trim, then we'll abort because that
8338                    // means it would be added at the end of the list but then just removed.
8339                    return -1;
8340                }
8341
8342                final int N = mRecentTasks.size();
8343                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8344                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8345                    tr.removedFromRecents(mTaskPersister);
8346                }
8347
8348                task.inRecents = true;
8349                mRecentTasks.add(task);
8350                r.task.stack.addTask(task, false, false);
8351
8352                task.setLastThumbnail(thumbnail);
8353                task.freeLastThumbnail();
8354
8355                return task.taskId;
8356            }
8357        } finally {
8358            Binder.restoreCallingIdentity(callingIdent);
8359        }
8360    }
8361
8362    @Override
8363    public Point getAppTaskThumbnailSize() {
8364        synchronized (this) {
8365            return new Point(mThumbnailWidth,  mThumbnailHeight);
8366        }
8367    }
8368
8369    @Override
8370    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8371        synchronized (this) {
8372            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8373            if (r != null) {
8374                r.setTaskDescription(td);
8375                r.task.updateTaskDescription();
8376            }
8377        }
8378    }
8379
8380    @Override
8381    public Bitmap getTaskDescriptionIcon(String filename) {
8382        return mTaskPersister.getTaskDescriptionIcon(filename);
8383    }
8384
8385    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8386        mRecentTasks.remove(tr);
8387        tr.removedFromRecents(mTaskPersister);
8388        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8389        Intent baseIntent = new Intent(
8390                tr.intent != null ? tr.intent : tr.affinityIntent);
8391        ComponentName component = baseIntent.getComponent();
8392        if (component == null) {
8393            Slog.w(TAG, "Now component for base intent of task: " + tr);
8394            return;
8395        }
8396
8397        // Find any running services associated with this app.
8398        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8399
8400        if (killProcesses) {
8401            // Find any running processes associated with this app.
8402            final String pkg = component.getPackageName();
8403            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8404            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8405            for (int i=0; i<pmap.size(); i++) {
8406                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8407                for (int j=0; j<uids.size(); j++) {
8408                    ProcessRecord proc = uids.valueAt(j);
8409                    if (proc.userId != tr.userId) {
8410                        continue;
8411                    }
8412                    if (!proc.pkgList.containsKey(pkg)) {
8413                        continue;
8414                    }
8415                    procs.add(proc);
8416                }
8417            }
8418
8419            // Kill the running processes.
8420            for (int i=0; i<procs.size(); i++) {
8421                ProcessRecord pr = procs.get(i);
8422                if (pr == mHomeProcess) {
8423                    // Don't kill the home process along with tasks from the same package.
8424                    continue;
8425                }
8426                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8427                    pr.kill("remove task", true);
8428                } else {
8429                    pr.waitingToKill = "remove task";
8430                }
8431            }
8432        }
8433    }
8434
8435    /**
8436     * Removes the task with the specified task id.
8437     *
8438     * @param taskId Identifier of the task to be removed.
8439     * @param flags Additional operational flags.  May be 0 or
8440     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8441     * @return Returns true if the given task was found and removed.
8442     */
8443    private boolean removeTaskByIdLocked(int taskId, int flags) {
8444        TaskRecord tr = recentTaskForIdLocked(taskId);
8445        if (tr != null) {
8446            tr.removeTaskActivitiesLocked();
8447            cleanUpRemovedTaskLocked(tr, flags);
8448            if (tr.isPersistable) {
8449                notifyTaskPersisterLocked(null, true);
8450            }
8451            return true;
8452        }
8453        return false;
8454    }
8455
8456    @Override
8457    public boolean removeTask(int taskId, int flags) {
8458        synchronized (this) {
8459            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8460                    "removeTask()");
8461            long ident = Binder.clearCallingIdentity();
8462            try {
8463                return removeTaskByIdLocked(taskId, flags);
8464            } finally {
8465                Binder.restoreCallingIdentity(ident);
8466            }
8467        }
8468    }
8469
8470    /**
8471     * TODO: Add mController hook
8472     */
8473    @Override
8474    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8475        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8476                "moveTaskToFront()");
8477
8478        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8479        synchronized(this) {
8480            moveTaskToFrontLocked(taskId, flags, options);
8481        }
8482    }
8483
8484    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8485        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8486                Binder.getCallingUid(), -1, -1, "Task to front")) {
8487            ActivityOptions.abort(options);
8488            return;
8489        }
8490        final long origId = Binder.clearCallingIdentity();
8491        try {
8492            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8493            if (task == null) {
8494                return;
8495            }
8496            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8497                mStackSupervisor.showLockTaskToast();
8498                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8499                return;
8500            }
8501            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8502            if (prev != null && prev.isRecentsActivity()) {
8503                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8504            }
8505            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8506        } finally {
8507            Binder.restoreCallingIdentity(origId);
8508        }
8509        ActivityOptions.abort(options);
8510    }
8511
8512    @Override
8513    public void moveTaskToBack(int taskId) {
8514        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8515                "moveTaskToBack()");
8516
8517        synchronized(this) {
8518            TaskRecord tr = recentTaskForIdLocked(taskId);
8519            if (tr != null) {
8520                if (tr == mStackSupervisor.mLockTaskModeTask) {
8521                    mStackSupervisor.showLockTaskToast();
8522                    return;
8523                }
8524                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8525                ActivityStack stack = tr.stack;
8526                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8527                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8528                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8529                        return;
8530                    }
8531                }
8532                final long origId = Binder.clearCallingIdentity();
8533                try {
8534                    stack.moveTaskToBackLocked(taskId, null);
8535                } finally {
8536                    Binder.restoreCallingIdentity(origId);
8537                }
8538            }
8539        }
8540    }
8541
8542    /**
8543     * Moves an activity, and all of the other activities within the same task, to the bottom
8544     * of the history stack.  The activity's order within the task is unchanged.
8545     *
8546     * @param token A reference to the activity we wish to move
8547     * @param nonRoot If false then this only works if the activity is the root
8548     *                of a task; if true it will work for any activity in a task.
8549     * @return Returns true if the move completed, false if not.
8550     */
8551    @Override
8552    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8553        enforceNotIsolatedCaller("moveActivityTaskToBack");
8554        synchronized(this) {
8555            final long origId = Binder.clearCallingIdentity();
8556            try {
8557                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8558                if (taskId >= 0) {
8559                    if ((mStackSupervisor.mLockTaskModeTask != null)
8560                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8561                        mStackSupervisor.showLockTaskToast();
8562                        return false;
8563                    }
8564                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8565                }
8566            } finally {
8567                Binder.restoreCallingIdentity(origId);
8568            }
8569        }
8570        return false;
8571    }
8572
8573    @Override
8574    public void moveTaskBackwards(int task) {
8575        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8576                "moveTaskBackwards()");
8577
8578        synchronized(this) {
8579            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8580                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8581                return;
8582            }
8583            final long origId = Binder.clearCallingIdentity();
8584            moveTaskBackwardsLocked(task);
8585            Binder.restoreCallingIdentity(origId);
8586        }
8587    }
8588
8589    private final void moveTaskBackwardsLocked(int task) {
8590        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8591    }
8592
8593    @Override
8594    public IBinder getHomeActivityToken() throws RemoteException {
8595        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8596                "getHomeActivityToken()");
8597        synchronized (this) {
8598            return mStackSupervisor.getHomeActivityToken();
8599        }
8600    }
8601
8602    @Override
8603    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8604            IActivityContainerCallback callback) throws RemoteException {
8605        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8606                "createActivityContainer()");
8607        synchronized (this) {
8608            if (parentActivityToken == null) {
8609                throw new IllegalArgumentException("parent token must not be null");
8610            }
8611            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8612            if (r == null) {
8613                return null;
8614            }
8615            if (callback == null) {
8616                throw new IllegalArgumentException("callback must not be null");
8617            }
8618            return mStackSupervisor.createActivityContainer(r, callback);
8619        }
8620    }
8621
8622    @Override
8623    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8624        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8625                "deleteActivityContainer()");
8626        synchronized (this) {
8627            mStackSupervisor.deleteActivityContainer(container);
8628        }
8629    }
8630
8631    @Override
8632    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8633            throws RemoteException {
8634        synchronized (this) {
8635            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8636            if (stack != null) {
8637                return stack.mActivityContainer;
8638            }
8639            return null;
8640        }
8641    }
8642
8643    @Override
8644    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8645        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8646                "moveTaskToStack()");
8647        if (stackId == HOME_STACK_ID) {
8648            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8649                    new RuntimeException("here").fillInStackTrace());
8650        }
8651        synchronized (this) {
8652            long ident = Binder.clearCallingIdentity();
8653            try {
8654                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8655                        + stackId + " toTop=" + toTop);
8656                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8657            } finally {
8658                Binder.restoreCallingIdentity(ident);
8659            }
8660        }
8661    }
8662
8663    @Override
8664    public void resizeStack(int stackBoxId, Rect bounds) {
8665        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8666                "resizeStackBox()");
8667        long ident = Binder.clearCallingIdentity();
8668        try {
8669            mWindowManager.resizeStack(stackBoxId, bounds);
8670        } finally {
8671            Binder.restoreCallingIdentity(ident);
8672        }
8673    }
8674
8675    @Override
8676    public List<StackInfo> getAllStackInfos() {
8677        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8678                "getAllStackInfos()");
8679        long ident = Binder.clearCallingIdentity();
8680        try {
8681            synchronized (this) {
8682                return mStackSupervisor.getAllStackInfosLocked();
8683            }
8684        } finally {
8685            Binder.restoreCallingIdentity(ident);
8686        }
8687    }
8688
8689    @Override
8690    public StackInfo getStackInfo(int stackId) {
8691        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8692                "getStackInfo()");
8693        long ident = Binder.clearCallingIdentity();
8694        try {
8695            synchronized (this) {
8696                return mStackSupervisor.getStackInfoLocked(stackId);
8697            }
8698        } finally {
8699            Binder.restoreCallingIdentity(ident);
8700        }
8701    }
8702
8703    @Override
8704    public boolean isInHomeStack(int taskId) {
8705        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8706                "getStackInfo()");
8707        long ident = Binder.clearCallingIdentity();
8708        try {
8709            synchronized (this) {
8710                TaskRecord tr = recentTaskForIdLocked(taskId);
8711                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8712            }
8713        } finally {
8714            Binder.restoreCallingIdentity(ident);
8715        }
8716    }
8717
8718    @Override
8719    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8720        synchronized(this) {
8721            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8722        }
8723    }
8724
8725    private boolean isLockTaskAuthorized(String pkg) {
8726        final DevicePolicyManager dpm = (DevicePolicyManager)
8727                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8728        try {
8729            int uid = mContext.getPackageManager().getPackageUid(pkg,
8730                    Binder.getCallingUserHandle().getIdentifier());
8731            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8732        } catch (NameNotFoundException e) {
8733            return false;
8734        }
8735    }
8736
8737    void startLockTaskMode(TaskRecord task) {
8738        final String pkg;
8739        synchronized (this) {
8740            pkg = task.intent.getComponent().getPackageName();
8741        }
8742        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8743        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8744            final TaskRecord taskRecord = task;
8745            mHandler.post(new Runnable() {
8746                @Override
8747                public void run() {
8748                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8749                }
8750            });
8751            return;
8752        }
8753        long ident = Binder.clearCallingIdentity();
8754        try {
8755            synchronized (this) {
8756                // Since we lost lock on task, make sure it is still there.
8757                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8758                if (task != null) {
8759                    if (!isSystemInitiated
8760                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8761                        throw new IllegalArgumentException("Invalid task, not in foreground");
8762                    }
8763                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8764                }
8765            }
8766        } finally {
8767            Binder.restoreCallingIdentity(ident);
8768        }
8769    }
8770
8771    @Override
8772    public void startLockTaskMode(int taskId) {
8773        final TaskRecord task;
8774        long ident = Binder.clearCallingIdentity();
8775        try {
8776            synchronized (this) {
8777                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8778            }
8779        } finally {
8780            Binder.restoreCallingIdentity(ident);
8781        }
8782        if (task != null) {
8783            startLockTaskMode(task);
8784        }
8785    }
8786
8787    @Override
8788    public void startLockTaskMode(IBinder token) {
8789        final TaskRecord task;
8790        long ident = Binder.clearCallingIdentity();
8791        try {
8792            synchronized (this) {
8793                final ActivityRecord r = ActivityRecord.forToken(token);
8794                if (r == null) {
8795                    return;
8796                }
8797                task = r.task;
8798            }
8799        } finally {
8800            Binder.restoreCallingIdentity(ident);
8801        }
8802        if (task != null) {
8803            startLockTaskMode(task);
8804        }
8805    }
8806
8807    @Override
8808    public void startLockTaskModeOnCurrent() throws RemoteException {
8809        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8810                "startLockTaskModeOnCurrent");
8811        ActivityRecord r = null;
8812        synchronized (this) {
8813            r = mStackSupervisor.topRunningActivityLocked();
8814        }
8815        startLockTaskMode(r.task);
8816    }
8817
8818    @Override
8819    public void stopLockTaskMode() {
8820        // Verify that the user matches the package of the intent for the TaskRecord
8821        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8822        // and stopLockTaskMode.
8823        final int callingUid = Binder.getCallingUid();
8824        if (callingUid != Process.SYSTEM_UID) {
8825            try {
8826                String pkg =
8827                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8828                int uid = mContext.getPackageManager().getPackageUid(pkg,
8829                        Binder.getCallingUserHandle().getIdentifier());
8830                if (uid != callingUid) {
8831                    throw new SecurityException("Invalid uid, expected " + uid);
8832                }
8833            } catch (NameNotFoundException e) {
8834                Log.d(TAG, "stopLockTaskMode " + e);
8835                return;
8836            }
8837        }
8838        long ident = Binder.clearCallingIdentity();
8839        try {
8840            Log.d(TAG, "stopLockTaskMode");
8841            // Stop lock task
8842            synchronized (this) {
8843                mStackSupervisor.setLockTaskModeLocked(null, false);
8844            }
8845        } finally {
8846            Binder.restoreCallingIdentity(ident);
8847        }
8848    }
8849
8850    @Override
8851    public void stopLockTaskModeOnCurrent() throws RemoteException {
8852        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8853                "stopLockTaskModeOnCurrent");
8854        long ident = Binder.clearCallingIdentity();
8855        try {
8856            stopLockTaskMode();
8857        } finally {
8858            Binder.restoreCallingIdentity(ident);
8859        }
8860    }
8861
8862    @Override
8863    public boolean isInLockTaskMode() {
8864        synchronized (this) {
8865            return mStackSupervisor.isInLockTaskMode();
8866        }
8867    }
8868
8869    // =========================================================
8870    // CONTENT PROVIDERS
8871    // =========================================================
8872
8873    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8874        List<ProviderInfo> providers = null;
8875        try {
8876            providers = AppGlobals.getPackageManager().
8877                queryContentProviders(app.processName, app.uid,
8878                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8879        } catch (RemoteException ex) {
8880        }
8881        if (DEBUG_MU)
8882            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8883        int userId = app.userId;
8884        if (providers != null) {
8885            int N = providers.size();
8886            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8887            for (int i=0; i<N; i++) {
8888                ProviderInfo cpi =
8889                    (ProviderInfo)providers.get(i);
8890                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8891                        cpi.name, cpi.flags);
8892                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8893                    // This is a singleton provider, but a user besides the
8894                    // default user is asking to initialize a process it runs
8895                    // in...  well, no, it doesn't actually run in this process,
8896                    // it runs in the process of the default user.  Get rid of it.
8897                    providers.remove(i);
8898                    N--;
8899                    i--;
8900                    continue;
8901                }
8902
8903                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8904                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8905                if (cpr == null) {
8906                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8907                    mProviderMap.putProviderByClass(comp, cpr);
8908                }
8909                if (DEBUG_MU)
8910                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8911                app.pubProviders.put(cpi.name, cpr);
8912                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8913                    // Don't add this if it is a platform component that is marked
8914                    // to run in multiple processes, because this is actually
8915                    // part of the framework so doesn't make sense to track as a
8916                    // separate apk in the process.
8917                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8918                            mProcessStats);
8919                }
8920                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8921            }
8922        }
8923        return providers;
8924    }
8925
8926    /**
8927     * Check if {@link ProcessRecord} has a possible chance at accessing the
8928     * given {@link ProviderInfo}. Final permission checking is always done
8929     * in {@link ContentProvider}.
8930     */
8931    private final String checkContentProviderPermissionLocked(
8932            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8933        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8934        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8935        boolean checkedGrants = false;
8936        if (checkUser) {
8937            // Looking for cross-user grants before enforcing the typical cross-users permissions
8938            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8939            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8940                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8941                    return null;
8942                }
8943                checkedGrants = true;
8944            }
8945            userId = handleIncomingUser(callingPid, callingUid, userId,
8946                    false, ALLOW_NON_FULL,
8947                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8948            if (userId != tmpTargetUserId) {
8949                // When we actually went to determine the final targer user ID, this ended
8950                // up different than our initial check for the authority.  This is because
8951                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8952                // SELF.  So we need to re-check the grants again.
8953                checkedGrants = false;
8954            }
8955        }
8956        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8957                cpi.applicationInfo.uid, cpi.exported)
8958                == PackageManager.PERMISSION_GRANTED) {
8959            return null;
8960        }
8961        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8962                cpi.applicationInfo.uid, cpi.exported)
8963                == PackageManager.PERMISSION_GRANTED) {
8964            return null;
8965        }
8966
8967        PathPermission[] pps = cpi.pathPermissions;
8968        if (pps != null) {
8969            int i = pps.length;
8970            while (i > 0) {
8971                i--;
8972                PathPermission pp = pps[i];
8973                String pprperm = pp.getReadPermission();
8974                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8975                        cpi.applicationInfo.uid, cpi.exported)
8976                        == PackageManager.PERMISSION_GRANTED) {
8977                    return null;
8978                }
8979                String ppwperm = pp.getWritePermission();
8980                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8981                        cpi.applicationInfo.uid, cpi.exported)
8982                        == PackageManager.PERMISSION_GRANTED) {
8983                    return null;
8984                }
8985            }
8986        }
8987        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8988            return null;
8989        }
8990
8991        String msg;
8992        if (!cpi.exported) {
8993            msg = "Permission Denial: opening provider " + cpi.name
8994                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8995                    + ", uid=" + callingUid + ") that is not exported from uid "
8996                    + cpi.applicationInfo.uid;
8997        } else {
8998            msg = "Permission Denial: opening provider " + cpi.name
8999                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9000                    + ", uid=" + callingUid + ") requires "
9001                    + cpi.readPermission + " or " + cpi.writePermission;
9002        }
9003        Slog.w(TAG, msg);
9004        return msg;
9005    }
9006
9007    /**
9008     * Returns if the ContentProvider has granted a uri to callingUid
9009     */
9010    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9011        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9012        if (perms != null) {
9013            for (int i=perms.size()-1; i>=0; i--) {
9014                GrantUri grantUri = perms.keyAt(i);
9015                if (grantUri.sourceUserId == userId || !checkUser) {
9016                    if (matchesProvider(grantUri.uri, cpi)) {
9017                        return true;
9018                    }
9019                }
9020            }
9021        }
9022        return false;
9023    }
9024
9025    /**
9026     * Returns true if the uri authority is one of the authorities specified in the provider.
9027     */
9028    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9029        String uriAuth = uri.getAuthority();
9030        String cpiAuth = cpi.authority;
9031        if (cpiAuth.indexOf(';') == -1) {
9032            return cpiAuth.equals(uriAuth);
9033        }
9034        String[] cpiAuths = cpiAuth.split(";");
9035        int length = cpiAuths.length;
9036        for (int i = 0; i < length; i++) {
9037            if (cpiAuths[i].equals(uriAuth)) return true;
9038        }
9039        return false;
9040    }
9041
9042    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9043            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9044        if (r != null) {
9045            for (int i=0; i<r.conProviders.size(); i++) {
9046                ContentProviderConnection conn = r.conProviders.get(i);
9047                if (conn.provider == cpr) {
9048                    if (DEBUG_PROVIDER) Slog.v(TAG,
9049                            "Adding provider requested by "
9050                            + r.processName + " from process "
9051                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9052                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9053                    if (stable) {
9054                        conn.stableCount++;
9055                        conn.numStableIncs++;
9056                    } else {
9057                        conn.unstableCount++;
9058                        conn.numUnstableIncs++;
9059                    }
9060                    return conn;
9061                }
9062            }
9063            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9064            if (stable) {
9065                conn.stableCount = 1;
9066                conn.numStableIncs = 1;
9067            } else {
9068                conn.unstableCount = 1;
9069                conn.numUnstableIncs = 1;
9070            }
9071            cpr.connections.add(conn);
9072            r.conProviders.add(conn);
9073            return conn;
9074        }
9075        cpr.addExternalProcessHandleLocked(externalProcessToken);
9076        return null;
9077    }
9078
9079    boolean decProviderCountLocked(ContentProviderConnection conn,
9080            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9081        if (conn != null) {
9082            cpr = conn.provider;
9083            if (DEBUG_PROVIDER) Slog.v(TAG,
9084                    "Removing provider requested by "
9085                    + conn.client.processName + " from process "
9086                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9087                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9088            if (stable) {
9089                conn.stableCount--;
9090            } else {
9091                conn.unstableCount--;
9092            }
9093            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9094                cpr.connections.remove(conn);
9095                conn.client.conProviders.remove(conn);
9096                return true;
9097            }
9098            return false;
9099        }
9100        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9101        return false;
9102    }
9103
9104    private void checkTime(long startTime, String where) {
9105        long now = SystemClock.elapsedRealtime();
9106        if ((now-startTime) > 1000) {
9107            // If we are taking more than a second, log about it.
9108            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9109        }
9110    }
9111
9112    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9113            String name, IBinder token, boolean stable, int userId) {
9114        ContentProviderRecord cpr;
9115        ContentProviderConnection conn = null;
9116        ProviderInfo cpi = null;
9117
9118        synchronized(this) {
9119            long startTime = SystemClock.elapsedRealtime();
9120
9121            ProcessRecord r = null;
9122            if (caller != null) {
9123                r = getRecordForAppLocked(caller);
9124                if (r == null) {
9125                    throw new SecurityException(
9126                            "Unable to find app for caller " + caller
9127                          + " (pid=" + Binder.getCallingPid()
9128                          + ") when getting content provider " + name);
9129                }
9130            }
9131
9132            boolean checkCrossUser = true;
9133
9134            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9135
9136            // First check if this content provider has been published...
9137            cpr = mProviderMap.getProviderByName(name, userId);
9138            // If that didn't work, check if it exists for user 0 and then
9139            // verify that it's a singleton provider before using it.
9140            if (cpr == null && userId != UserHandle.USER_OWNER) {
9141                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9142                if (cpr != null) {
9143                    cpi = cpr.info;
9144                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9145                            cpi.name, cpi.flags)
9146                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9147                        userId = UserHandle.USER_OWNER;
9148                        checkCrossUser = false;
9149                    } else {
9150                        cpr = null;
9151                        cpi = null;
9152                    }
9153                }
9154            }
9155
9156            boolean providerRunning = cpr != null;
9157            if (providerRunning) {
9158                cpi = cpr.info;
9159                String msg;
9160                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9161                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9162                        != null) {
9163                    throw new SecurityException(msg);
9164                }
9165                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9166
9167                if (r != null && cpr.canRunHere(r)) {
9168                    // This provider has been published or is in the process
9169                    // of being published...  but it is also allowed to run
9170                    // in the caller's process, so don't make a connection
9171                    // and just let the caller instantiate its own instance.
9172                    ContentProviderHolder holder = cpr.newHolder(null);
9173                    // don't give caller the provider object, it needs
9174                    // to make its own.
9175                    holder.provider = null;
9176                    return holder;
9177                }
9178
9179                final long origId = Binder.clearCallingIdentity();
9180
9181                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9182
9183                // In this case the provider instance already exists, so we can
9184                // return it right away.
9185                conn = incProviderCountLocked(r, cpr, token, stable);
9186                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9187                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9188                        // If this is a perceptible app accessing the provider,
9189                        // make sure to count it as being accessed and thus
9190                        // back up on the LRU list.  This is good because
9191                        // content providers are often expensive to start.
9192                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9193                        updateLruProcessLocked(cpr.proc, false, null);
9194                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9195                    }
9196                }
9197
9198                if (cpr.proc != null) {
9199                    if (false) {
9200                        if (cpr.name.flattenToShortString().equals(
9201                                "com.android.providers.calendar/.CalendarProvider2")) {
9202                            Slog.v(TAG, "****************** KILLING "
9203                                + cpr.name.flattenToShortString());
9204                            Process.killProcess(cpr.proc.pid);
9205                        }
9206                    }
9207                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9208                    boolean success = updateOomAdjLocked(cpr.proc);
9209                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9210                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9211                    // NOTE: there is still a race here where a signal could be
9212                    // pending on the process even though we managed to update its
9213                    // adj level.  Not sure what to do about this, but at least
9214                    // the race is now smaller.
9215                    if (!success) {
9216                        // Uh oh...  it looks like the provider's process
9217                        // has been killed on us.  We need to wait for a new
9218                        // process to be started, and make sure its death
9219                        // doesn't kill our process.
9220                        Slog.i(TAG,
9221                                "Existing provider " + cpr.name.flattenToShortString()
9222                                + " is crashing; detaching " + r);
9223                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9224                        checkTime(startTime, "getContentProviderImpl: before appDied");
9225                        appDiedLocked(cpr.proc);
9226                        checkTime(startTime, "getContentProviderImpl: after appDied");
9227                        if (!lastRef) {
9228                            // This wasn't the last ref our process had on
9229                            // the provider...  we have now been killed, bail.
9230                            return null;
9231                        }
9232                        providerRunning = false;
9233                        conn = null;
9234                    }
9235                }
9236
9237                Binder.restoreCallingIdentity(origId);
9238            }
9239
9240            boolean singleton;
9241            if (!providerRunning) {
9242                try {
9243                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9244                    cpi = AppGlobals.getPackageManager().
9245                        resolveContentProvider(name,
9246                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9247                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9248                } catch (RemoteException ex) {
9249                }
9250                if (cpi == null) {
9251                    return null;
9252                }
9253                // If the provider is a singleton AND
9254                // (it's a call within the same user || the provider is a
9255                // privileged app)
9256                // Then allow connecting to the singleton provider
9257                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9258                        cpi.name, cpi.flags)
9259                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9260                if (singleton) {
9261                    userId = UserHandle.USER_OWNER;
9262                }
9263                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9264                checkTime(startTime, "getContentProviderImpl: got app info for user");
9265
9266                String msg;
9267                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9268                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9269                        != null) {
9270                    throw new SecurityException(msg);
9271                }
9272                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9273
9274                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9275                        && !cpi.processName.equals("system")) {
9276                    // If this content provider does not run in the system
9277                    // process, and the system is not yet ready to run other
9278                    // processes, then fail fast instead of hanging.
9279                    throw new IllegalArgumentException(
9280                            "Attempt to launch content provider before system ready");
9281                }
9282
9283                // Make sure that the user who owns this provider is started.  If not,
9284                // we don't want to allow it to run.
9285                if (mStartedUsers.get(userId) == null) {
9286                    Slog.w(TAG, "Unable to launch app "
9287                            + cpi.applicationInfo.packageName + "/"
9288                            + cpi.applicationInfo.uid + " for provider "
9289                            + name + ": user " + userId + " is stopped");
9290                    return null;
9291                }
9292
9293                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9294                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9295                cpr = mProviderMap.getProviderByClass(comp, userId);
9296                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9297                final boolean firstClass = cpr == null;
9298                if (firstClass) {
9299                    try {
9300                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9301                        ApplicationInfo ai =
9302                            AppGlobals.getPackageManager().
9303                                getApplicationInfo(
9304                                        cpi.applicationInfo.packageName,
9305                                        STOCK_PM_FLAGS, userId);
9306                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9307                        if (ai == null) {
9308                            Slog.w(TAG, "No package info for content provider "
9309                                    + cpi.name);
9310                            return null;
9311                        }
9312                        ai = getAppInfoForUser(ai, userId);
9313                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9314                    } catch (RemoteException ex) {
9315                        // pm is in same process, this will never happen.
9316                    }
9317                }
9318
9319                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9320
9321                if (r != null && cpr.canRunHere(r)) {
9322                    // If this is a multiprocess provider, then just return its
9323                    // info and allow the caller to instantiate it.  Only do
9324                    // this if the provider is the same user as the caller's
9325                    // process, or can run as root (so can be in any process).
9326                    return cpr.newHolder(null);
9327                }
9328
9329                if (DEBUG_PROVIDER) {
9330                    RuntimeException e = new RuntimeException("here");
9331                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9332                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9333                }
9334
9335                // This is single process, and our app is now connecting to it.
9336                // See if we are already in the process of launching this
9337                // provider.
9338                final int N = mLaunchingProviders.size();
9339                int i;
9340                for (i=0; i<N; i++) {
9341                    if (mLaunchingProviders.get(i) == cpr) {
9342                        break;
9343                    }
9344                }
9345
9346                // If the provider is not already being launched, then get it
9347                // started.
9348                if (i >= N) {
9349                    final long origId = Binder.clearCallingIdentity();
9350
9351                    try {
9352                        // Content provider is now in use, its package can't be stopped.
9353                        try {
9354                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9355                            AppGlobals.getPackageManager().setPackageStoppedState(
9356                                    cpr.appInfo.packageName, false, userId);
9357                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9358                        } catch (RemoteException e) {
9359                        } catch (IllegalArgumentException e) {
9360                            Slog.w(TAG, "Failed trying to unstop package "
9361                                    + cpr.appInfo.packageName + ": " + e);
9362                        }
9363
9364                        // Use existing process if already started
9365                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9366                        ProcessRecord proc = getProcessRecordLocked(
9367                                cpi.processName, cpr.appInfo.uid, false);
9368                        if (proc != null && proc.thread != null) {
9369                            if (DEBUG_PROVIDER) {
9370                                Slog.d(TAG, "Installing in existing process " + proc);
9371                            }
9372                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9373                            proc.pubProviders.put(cpi.name, cpr);
9374                            try {
9375                                proc.thread.scheduleInstallProvider(cpi);
9376                            } catch (RemoteException e) {
9377                            }
9378                        } else {
9379                            checkTime(startTime, "getContentProviderImpl: before start process");
9380                            proc = startProcessLocked(cpi.processName,
9381                                    cpr.appInfo, false, 0, "content provider",
9382                                    new ComponentName(cpi.applicationInfo.packageName,
9383                                            cpi.name), false, false, false);
9384                            checkTime(startTime, "getContentProviderImpl: after start process");
9385                            if (proc == null) {
9386                                Slog.w(TAG, "Unable to launch app "
9387                                        + cpi.applicationInfo.packageName + "/"
9388                                        + cpi.applicationInfo.uid + " for provider "
9389                                        + name + ": process is bad");
9390                                return null;
9391                            }
9392                        }
9393                        cpr.launchingApp = proc;
9394                        mLaunchingProviders.add(cpr);
9395                    } finally {
9396                        Binder.restoreCallingIdentity(origId);
9397                    }
9398                }
9399
9400                checkTime(startTime, "getContentProviderImpl: updating data structures");
9401
9402                // Make sure the provider is published (the same provider class
9403                // may be published under multiple names).
9404                if (firstClass) {
9405                    mProviderMap.putProviderByClass(comp, cpr);
9406                }
9407
9408                mProviderMap.putProviderByName(name, cpr);
9409                conn = incProviderCountLocked(r, cpr, token, stable);
9410                if (conn != null) {
9411                    conn.waiting = true;
9412                }
9413            }
9414            checkTime(startTime, "getContentProviderImpl: done!");
9415        }
9416
9417        // Wait for the provider to be published...
9418        synchronized (cpr) {
9419            while (cpr.provider == null) {
9420                if (cpr.launchingApp == null) {
9421                    Slog.w(TAG, "Unable to launch app "
9422                            + cpi.applicationInfo.packageName + "/"
9423                            + cpi.applicationInfo.uid + " for provider "
9424                            + name + ": launching app became null");
9425                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9426                            UserHandle.getUserId(cpi.applicationInfo.uid),
9427                            cpi.applicationInfo.packageName,
9428                            cpi.applicationInfo.uid, name);
9429                    return null;
9430                }
9431                try {
9432                    if (DEBUG_MU) {
9433                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9434                                + cpr.launchingApp);
9435                    }
9436                    if (conn != null) {
9437                        conn.waiting = true;
9438                    }
9439                    cpr.wait();
9440                } catch (InterruptedException ex) {
9441                } finally {
9442                    if (conn != null) {
9443                        conn.waiting = false;
9444                    }
9445                }
9446            }
9447        }
9448        return cpr != null ? cpr.newHolder(conn) : null;
9449    }
9450
9451    @Override
9452    public final ContentProviderHolder getContentProvider(
9453            IApplicationThread caller, String name, int userId, boolean stable) {
9454        enforceNotIsolatedCaller("getContentProvider");
9455        if (caller == null) {
9456            String msg = "null IApplicationThread when getting content provider "
9457                    + name;
9458            Slog.w(TAG, msg);
9459            throw new SecurityException(msg);
9460        }
9461        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9462        // with cross-user grant.
9463        return getContentProviderImpl(caller, name, null, stable, userId);
9464    }
9465
9466    public ContentProviderHolder getContentProviderExternal(
9467            String name, int userId, IBinder token) {
9468        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9469            "Do not have permission in call getContentProviderExternal()");
9470        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9471                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9472        return getContentProviderExternalUnchecked(name, token, userId);
9473    }
9474
9475    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9476            IBinder token, int userId) {
9477        return getContentProviderImpl(null, name, token, true, userId);
9478    }
9479
9480    /**
9481     * Drop a content provider from a ProcessRecord's bookkeeping
9482     */
9483    public void removeContentProvider(IBinder connection, boolean stable) {
9484        enforceNotIsolatedCaller("removeContentProvider");
9485        long ident = Binder.clearCallingIdentity();
9486        try {
9487            synchronized (this) {
9488                ContentProviderConnection conn;
9489                try {
9490                    conn = (ContentProviderConnection)connection;
9491                } catch (ClassCastException e) {
9492                    String msg ="removeContentProvider: " + connection
9493                            + " not a ContentProviderConnection";
9494                    Slog.w(TAG, msg);
9495                    throw new IllegalArgumentException(msg);
9496                }
9497                if (conn == null) {
9498                    throw new NullPointerException("connection is null");
9499                }
9500                if (decProviderCountLocked(conn, null, null, stable)) {
9501                    updateOomAdjLocked();
9502                }
9503            }
9504        } finally {
9505            Binder.restoreCallingIdentity(ident);
9506        }
9507    }
9508
9509    public void removeContentProviderExternal(String name, IBinder token) {
9510        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9511            "Do not have permission in call removeContentProviderExternal()");
9512        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9513    }
9514
9515    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9516        synchronized (this) {
9517            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9518            if(cpr == null) {
9519                //remove from mProvidersByClass
9520                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9521                return;
9522            }
9523
9524            //update content provider record entry info
9525            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9526            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9527            if (localCpr.hasExternalProcessHandles()) {
9528                if (localCpr.removeExternalProcessHandleLocked(token)) {
9529                    updateOomAdjLocked();
9530                } else {
9531                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9532                            + " with no external reference for token: "
9533                            + token + ".");
9534                }
9535            } else {
9536                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9537                        + " with no external references.");
9538            }
9539        }
9540    }
9541
9542    public final void publishContentProviders(IApplicationThread caller,
9543            List<ContentProviderHolder> providers) {
9544        if (providers == null) {
9545            return;
9546        }
9547
9548        enforceNotIsolatedCaller("publishContentProviders");
9549        synchronized (this) {
9550            final ProcessRecord r = getRecordForAppLocked(caller);
9551            if (DEBUG_MU)
9552                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9553            if (r == null) {
9554                throw new SecurityException(
9555                        "Unable to find app for caller " + caller
9556                      + " (pid=" + Binder.getCallingPid()
9557                      + ") when publishing content providers");
9558            }
9559
9560            final long origId = Binder.clearCallingIdentity();
9561
9562            final int N = providers.size();
9563            for (int i=0; i<N; i++) {
9564                ContentProviderHolder src = providers.get(i);
9565                if (src == null || src.info == null || src.provider == null) {
9566                    continue;
9567                }
9568                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9569                if (DEBUG_MU)
9570                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9571                if (dst != null) {
9572                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9573                    mProviderMap.putProviderByClass(comp, dst);
9574                    String names[] = dst.info.authority.split(";");
9575                    for (int j = 0; j < names.length; j++) {
9576                        mProviderMap.putProviderByName(names[j], dst);
9577                    }
9578
9579                    int NL = mLaunchingProviders.size();
9580                    int j;
9581                    for (j=0; j<NL; j++) {
9582                        if (mLaunchingProviders.get(j) == dst) {
9583                            mLaunchingProviders.remove(j);
9584                            j--;
9585                            NL--;
9586                        }
9587                    }
9588                    synchronized (dst) {
9589                        dst.provider = src.provider;
9590                        dst.proc = r;
9591                        dst.notifyAll();
9592                    }
9593                    updateOomAdjLocked(r);
9594                }
9595            }
9596
9597            Binder.restoreCallingIdentity(origId);
9598        }
9599    }
9600
9601    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9602        ContentProviderConnection conn;
9603        try {
9604            conn = (ContentProviderConnection)connection;
9605        } catch (ClassCastException e) {
9606            String msg ="refContentProvider: " + connection
9607                    + " not a ContentProviderConnection";
9608            Slog.w(TAG, msg);
9609            throw new IllegalArgumentException(msg);
9610        }
9611        if (conn == null) {
9612            throw new NullPointerException("connection is null");
9613        }
9614
9615        synchronized (this) {
9616            if (stable > 0) {
9617                conn.numStableIncs += stable;
9618            }
9619            stable = conn.stableCount + stable;
9620            if (stable < 0) {
9621                throw new IllegalStateException("stableCount < 0: " + stable);
9622            }
9623
9624            if (unstable > 0) {
9625                conn.numUnstableIncs += unstable;
9626            }
9627            unstable = conn.unstableCount + unstable;
9628            if (unstable < 0) {
9629                throw new IllegalStateException("unstableCount < 0: " + unstable);
9630            }
9631
9632            if ((stable+unstable) <= 0) {
9633                throw new IllegalStateException("ref counts can't go to zero here: stable="
9634                        + stable + " unstable=" + unstable);
9635            }
9636            conn.stableCount = stable;
9637            conn.unstableCount = unstable;
9638            return !conn.dead;
9639        }
9640    }
9641
9642    public void unstableProviderDied(IBinder connection) {
9643        ContentProviderConnection conn;
9644        try {
9645            conn = (ContentProviderConnection)connection;
9646        } catch (ClassCastException e) {
9647            String msg ="refContentProvider: " + connection
9648                    + " not a ContentProviderConnection";
9649            Slog.w(TAG, msg);
9650            throw new IllegalArgumentException(msg);
9651        }
9652        if (conn == null) {
9653            throw new NullPointerException("connection is null");
9654        }
9655
9656        // Safely retrieve the content provider associated with the connection.
9657        IContentProvider provider;
9658        synchronized (this) {
9659            provider = conn.provider.provider;
9660        }
9661
9662        if (provider == null) {
9663            // Um, yeah, we're way ahead of you.
9664            return;
9665        }
9666
9667        // Make sure the caller is being honest with us.
9668        if (provider.asBinder().pingBinder()) {
9669            // Er, no, still looks good to us.
9670            synchronized (this) {
9671                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9672                        + " says " + conn + " died, but we don't agree");
9673                return;
9674            }
9675        }
9676
9677        // Well look at that!  It's dead!
9678        synchronized (this) {
9679            if (conn.provider.provider != provider) {
9680                // But something changed...  good enough.
9681                return;
9682            }
9683
9684            ProcessRecord proc = conn.provider.proc;
9685            if (proc == null || proc.thread == null) {
9686                // Seems like the process is already cleaned up.
9687                return;
9688            }
9689
9690            // As far as we're concerned, this is just like receiving a
9691            // death notification...  just a bit prematurely.
9692            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9693                    + ") early provider death");
9694            final long ident = Binder.clearCallingIdentity();
9695            try {
9696                appDiedLocked(proc);
9697            } finally {
9698                Binder.restoreCallingIdentity(ident);
9699            }
9700        }
9701    }
9702
9703    @Override
9704    public void appNotRespondingViaProvider(IBinder connection) {
9705        enforceCallingPermission(
9706                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9707
9708        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9709        if (conn == null) {
9710            Slog.w(TAG, "ContentProviderConnection is null");
9711            return;
9712        }
9713
9714        final ProcessRecord host = conn.provider.proc;
9715        if (host == null) {
9716            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9717            return;
9718        }
9719
9720        final long token = Binder.clearCallingIdentity();
9721        try {
9722            appNotResponding(host, null, null, false, "ContentProvider not responding");
9723        } finally {
9724            Binder.restoreCallingIdentity(token);
9725        }
9726    }
9727
9728    public final void installSystemProviders() {
9729        List<ProviderInfo> providers;
9730        synchronized (this) {
9731            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9732            providers = generateApplicationProvidersLocked(app);
9733            if (providers != null) {
9734                for (int i=providers.size()-1; i>=0; i--) {
9735                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9736                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9737                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9738                                + ": not system .apk");
9739                        providers.remove(i);
9740                    }
9741                }
9742            }
9743        }
9744        if (providers != null) {
9745            mSystemThread.installSystemProviders(providers);
9746        }
9747
9748        mCoreSettingsObserver = new CoreSettingsObserver(this);
9749
9750        //mUsageStatsService.monitorPackages();
9751    }
9752
9753    /**
9754     * Allows apps to retrieve the MIME type of a URI.
9755     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9756     * users, then it does not need permission to access the ContentProvider.
9757     * Either, it needs cross-user uri grants.
9758     *
9759     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9760     *
9761     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9762     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9763     */
9764    public String getProviderMimeType(Uri uri, int userId) {
9765        enforceNotIsolatedCaller("getProviderMimeType");
9766        final String name = uri.getAuthority();
9767        int callingUid = Binder.getCallingUid();
9768        int callingPid = Binder.getCallingPid();
9769        long ident = 0;
9770        boolean clearedIdentity = false;
9771        userId = unsafeConvertIncomingUser(userId);
9772        if (canClearIdentity(callingPid, callingUid, userId)) {
9773            clearedIdentity = true;
9774            ident = Binder.clearCallingIdentity();
9775        }
9776        ContentProviderHolder holder = null;
9777        try {
9778            holder = getContentProviderExternalUnchecked(name, null, userId);
9779            if (holder != null) {
9780                return holder.provider.getType(uri);
9781            }
9782        } catch (RemoteException e) {
9783            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9784            return null;
9785        } finally {
9786            // We need to clear the identity to call removeContentProviderExternalUnchecked
9787            if (!clearedIdentity) {
9788                ident = Binder.clearCallingIdentity();
9789            }
9790            try {
9791                if (holder != null) {
9792                    removeContentProviderExternalUnchecked(name, null, userId);
9793                }
9794            } finally {
9795                Binder.restoreCallingIdentity(ident);
9796            }
9797        }
9798
9799        return null;
9800    }
9801
9802    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9803        if (UserHandle.getUserId(callingUid) == userId) {
9804            return true;
9805        }
9806        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9807                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9808                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9809                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9810                return true;
9811        }
9812        return false;
9813    }
9814
9815    // =========================================================
9816    // GLOBAL MANAGEMENT
9817    // =========================================================
9818
9819    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9820            boolean isolated, int isolatedUid) {
9821        String proc = customProcess != null ? customProcess : info.processName;
9822        BatteryStatsImpl.Uid.Proc ps = null;
9823        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9824        int uid = info.uid;
9825        if (isolated) {
9826            if (isolatedUid == 0) {
9827                int userId = UserHandle.getUserId(uid);
9828                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9829                while (true) {
9830                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9831                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9832                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9833                    }
9834                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9835                    mNextIsolatedProcessUid++;
9836                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9837                        // No process for this uid, use it.
9838                        break;
9839                    }
9840                    stepsLeft--;
9841                    if (stepsLeft <= 0) {
9842                        return null;
9843                    }
9844                }
9845            } else {
9846                // Special case for startIsolatedProcess (internal only), where
9847                // the uid of the isolated process is specified by the caller.
9848                uid = isolatedUid;
9849            }
9850        }
9851        return new ProcessRecord(stats, info, proc, uid);
9852    }
9853
9854    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9855            String abiOverride) {
9856        ProcessRecord app;
9857        if (!isolated) {
9858            app = getProcessRecordLocked(info.processName, info.uid, true);
9859        } else {
9860            app = null;
9861        }
9862
9863        if (app == null) {
9864            app = newProcessRecordLocked(info, null, isolated, 0);
9865            mProcessNames.put(info.processName, app.uid, app);
9866            if (isolated) {
9867                mIsolatedProcesses.put(app.uid, app);
9868            }
9869            updateLruProcessLocked(app, false, null);
9870            updateOomAdjLocked();
9871        }
9872
9873        // This package really, really can not be stopped.
9874        try {
9875            AppGlobals.getPackageManager().setPackageStoppedState(
9876                    info.packageName, false, UserHandle.getUserId(app.uid));
9877        } catch (RemoteException e) {
9878        } catch (IllegalArgumentException e) {
9879            Slog.w(TAG, "Failed trying to unstop package "
9880                    + info.packageName + ": " + e);
9881        }
9882
9883        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9884                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9885            app.persistent = true;
9886            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9887        }
9888        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9889            mPersistentStartingProcesses.add(app);
9890            startProcessLocked(app, "added application", app.processName, abiOverride,
9891                    null /* entryPoint */, null /* entryPointArgs */);
9892        }
9893
9894        return app;
9895    }
9896
9897    public void unhandledBack() {
9898        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9899                "unhandledBack()");
9900
9901        synchronized(this) {
9902            final long origId = Binder.clearCallingIdentity();
9903            try {
9904                getFocusedStack().unhandledBackLocked();
9905            } finally {
9906                Binder.restoreCallingIdentity(origId);
9907            }
9908        }
9909    }
9910
9911    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9912        enforceNotIsolatedCaller("openContentUri");
9913        final int userId = UserHandle.getCallingUserId();
9914        String name = uri.getAuthority();
9915        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9916        ParcelFileDescriptor pfd = null;
9917        if (cph != null) {
9918            // We record the binder invoker's uid in thread-local storage before
9919            // going to the content provider to open the file.  Later, in the code
9920            // that handles all permissions checks, we look for this uid and use
9921            // that rather than the Activity Manager's own uid.  The effect is that
9922            // we do the check against the caller's permissions even though it looks
9923            // to the content provider like the Activity Manager itself is making
9924            // the request.
9925            sCallerIdentity.set(new Identity(
9926                    Binder.getCallingPid(), Binder.getCallingUid()));
9927            try {
9928                pfd = cph.provider.openFile(null, uri, "r", null);
9929            } catch (FileNotFoundException e) {
9930                // do nothing; pfd will be returned null
9931            } finally {
9932                // Ensure that whatever happens, we clean up the identity state
9933                sCallerIdentity.remove();
9934            }
9935
9936            // We've got the fd now, so we're done with the provider.
9937            removeContentProviderExternalUnchecked(name, null, userId);
9938        } else {
9939            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9940        }
9941        return pfd;
9942    }
9943
9944    // Actually is sleeping or shutting down or whatever else in the future
9945    // is an inactive state.
9946    public boolean isSleepingOrShuttingDown() {
9947        return isSleeping() || mShuttingDown;
9948    }
9949
9950    public boolean isSleeping() {
9951        return mSleeping;
9952    }
9953
9954    void goingToSleep() {
9955        synchronized(this) {
9956            mWentToSleep = true;
9957            goToSleepIfNeededLocked();
9958        }
9959    }
9960
9961    void finishRunningVoiceLocked() {
9962        if (mRunningVoice) {
9963            mRunningVoice = false;
9964            goToSleepIfNeededLocked();
9965        }
9966    }
9967
9968    void goToSleepIfNeededLocked() {
9969        if (mWentToSleep && !mRunningVoice) {
9970            if (!mSleeping) {
9971                mSleeping = true;
9972                mStackSupervisor.goingToSleepLocked();
9973
9974                // Initialize the wake times of all processes.
9975                checkExcessivePowerUsageLocked(false);
9976                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9977                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9978                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9979            }
9980        }
9981    }
9982
9983    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9984        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9985            // Never persist the home stack.
9986            return;
9987        }
9988        mTaskPersister.wakeup(task, flush);
9989    }
9990
9991    @Override
9992    public boolean shutdown(int timeout) {
9993        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9994                != PackageManager.PERMISSION_GRANTED) {
9995            throw new SecurityException("Requires permission "
9996                    + android.Manifest.permission.SHUTDOWN);
9997        }
9998
9999        boolean timedout = false;
10000
10001        synchronized(this) {
10002            mShuttingDown = true;
10003            updateEventDispatchingLocked();
10004            timedout = mStackSupervisor.shutdownLocked(timeout);
10005        }
10006
10007        mAppOpsService.shutdown();
10008        if (mUsageStatsService != null) {
10009            mUsageStatsService.prepareShutdown();
10010        }
10011        mBatteryStatsService.shutdown();
10012        synchronized (this) {
10013            mProcessStats.shutdownLocked();
10014        }
10015        notifyTaskPersisterLocked(null, true);
10016
10017        return timedout;
10018    }
10019
10020    public final void activitySlept(IBinder token) {
10021        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10022
10023        final long origId = Binder.clearCallingIdentity();
10024
10025        synchronized (this) {
10026            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10027            if (r != null) {
10028                mStackSupervisor.activitySleptLocked(r);
10029            }
10030        }
10031
10032        Binder.restoreCallingIdentity(origId);
10033    }
10034
10035    void logLockScreen(String msg) {
10036        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10037                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10038                mWentToSleep + " mSleeping=" + mSleeping);
10039    }
10040
10041    private void comeOutOfSleepIfNeededLocked() {
10042        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10043            if (mSleeping) {
10044                mSleeping = false;
10045                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10046            }
10047        }
10048    }
10049
10050    void wakingUp() {
10051        synchronized(this) {
10052            mWentToSleep = false;
10053            comeOutOfSleepIfNeededLocked();
10054        }
10055    }
10056
10057    void startRunningVoiceLocked() {
10058        if (!mRunningVoice) {
10059            mRunningVoice = true;
10060            comeOutOfSleepIfNeededLocked();
10061        }
10062    }
10063
10064    private void updateEventDispatchingLocked() {
10065        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10066    }
10067
10068    public void setLockScreenShown(boolean shown) {
10069        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10070                != PackageManager.PERMISSION_GRANTED) {
10071            throw new SecurityException("Requires permission "
10072                    + android.Manifest.permission.DEVICE_POWER);
10073        }
10074
10075        synchronized(this) {
10076            long ident = Binder.clearCallingIdentity();
10077            try {
10078                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10079                mLockScreenShown = shown;
10080                comeOutOfSleepIfNeededLocked();
10081            } finally {
10082                Binder.restoreCallingIdentity(ident);
10083            }
10084        }
10085    }
10086
10087    @Override
10088    public void stopAppSwitches() {
10089        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10090                != PackageManager.PERMISSION_GRANTED) {
10091            throw new SecurityException("Requires permission "
10092                    + android.Manifest.permission.STOP_APP_SWITCHES);
10093        }
10094
10095        synchronized(this) {
10096            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10097                    + APP_SWITCH_DELAY_TIME;
10098            mDidAppSwitch = false;
10099            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10100            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10101            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10102        }
10103    }
10104
10105    public void resumeAppSwitches() {
10106        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10107                != PackageManager.PERMISSION_GRANTED) {
10108            throw new SecurityException("Requires permission "
10109                    + android.Manifest.permission.STOP_APP_SWITCHES);
10110        }
10111
10112        synchronized(this) {
10113            // Note that we don't execute any pending app switches... we will
10114            // let those wait until either the timeout, or the next start
10115            // activity request.
10116            mAppSwitchesAllowedTime = 0;
10117        }
10118    }
10119
10120    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10121            int callingPid, int callingUid, String name) {
10122        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10123            return true;
10124        }
10125
10126        int perm = checkComponentPermission(
10127                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10128                sourceUid, -1, true);
10129        if (perm == PackageManager.PERMISSION_GRANTED) {
10130            return true;
10131        }
10132
10133        // If the actual IPC caller is different from the logical source, then
10134        // also see if they are allowed to control app switches.
10135        if (callingUid != -1 && callingUid != sourceUid) {
10136            perm = checkComponentPermission(
10137                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10138                    callingUid, -1, true);
10139            if (perm == PackageManager.PERMISSION_GRANTED) {
10140                return true;
10141            }
10142        }
10143
10144        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10145        return false;
10146    }
10147
10148    public void setDebugApp(String packageName, boolean waitForDebugger,
10149            boolean persistent) {
10150        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10151                "setDebugApp()");
10152
10153        long ident = Binder.clearCallingIdentity();
10154        try {
10155            // Note that this is not really thread safe if there are multiple
10156            // callers into it at the same time, but that's not a situation we
10157            // care about.
10158            if (persistent) {
10159                final ContentResolver resolver = mContext.getContentResolver();
10160                Settings.Global.putString(
10161                    resolver, Settings.Global.DEBUG_APP,
10162                    packageName);
10163                Settings.Global.putInt(
10164                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10165                    waitForDebugger ? 1 : 0);
10166            }
10167
10168            synchronized (this) {
10169                if (!persistent) {
10170                    mOrigDebugApp = mDebugApp;
10171                    mOrigWaitForDebugger = mWaitForDebugger;
10172                }
10173                mDebugApp = packageName;
10174                mWaitForDebugger = waitForDebugger;
10175                mDebugTransient = !persistent;
10176                if (packageName != null) {
10177                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10178                            false, UserHandle.USER_ALL, "set debug app");
10179                }
10180            }
10181        } finally {
10182            Binder.restoreCallingIdentity(ident);
10183        }
10184    }
10185
10186    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10187        synchronized (this) {
10188            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10189            if (!isDebuggable) {
10190                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10191                    throw new SecurityException("Process not debuggable: " + app.packageName);
10192                }
10193            }
10194
10195            mOpenGlTraceApp = processName;
10196        }
10197    }
10198
10199    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10200        synchronized (this) {
10201            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10202            if (!isDebuggable) {
10203                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10204                    throw new SecurityException("Process not debuggable: " + app.packageName);
10205                }
10206            }
10207            mProfileApp = processName;
10208            mProfileFile = profilerInfo.profileFile;
10209            if (mProfileFd != null) {
10210                try {
10211                    mProfileFd.close();
10212                } catch (IOException e) {
10213                }
10214                mProfileFd = null;
10215            }
10216            mProfileFd = profilerInfo.profileFd;
10217            mSamplingInterval = profilerInfo.samplingInterval;
10218            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10219            mProfileType = 0;
10220        }
10221    }
10222
10223    @Override
10224    public void setAlwaysFinish(boolean enabled) {
10225        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10226                "setAlwaysFinish()");
10227
10228        Settings.Global.putInt(
10229                mContext.getContentResolver(),
10230                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10231
10232        synchronized (this) {
10233            mAlwaysFinishActivities = enabled;
10234        }
10235    }
10236
10237    @Override
10238    public void setActivityController(IActivityController controller) {
10239        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10240                "setActivityController()");
10241        synchronized (this) {
10242            mController = controller;
10243            Watchdog.getInstance().setActivityController(controller);
10244        }
10245    }
10246
10247    @Override
10248    public void setUserIsMonkey(boolean userIsMonkey) {
10249        synchronized (this) {
10250            synchronized (mPidsSelfLocked) {
10251                final int callingPid = Binder.getCallingPid();
10252                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10253                if (precessRecord == null) {
10254                    throw new SecurityException("Unknown process: " + callingPid);
10255                }
10256                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10257                    throw new SecurityException("Only an instrumentation process "
10258                            + "with a UiAutomation can call setUserIsMonkey");
10259                }
10260            }
10261            mUserIsMonkey = userIsMonkey;
10262        }
10263    }
10264
10265    @Override
10266    public boolean isUserAMonkey() {
10267        synchronized (this) {
10268            // If there is a controller also implies the user is a monkey.
10269            return (mUserIsMonkey || mController != null);
10270        }
10271    }
10272
10273    public void requestBugReport() {
10274        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10275        SystemProperties.set("ctl.start", "bugreport");
10276    }
10277
10278    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10279        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10280    }
10281
10282    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10283        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10284            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10285        }
10286        return KEY_DISPATCHING_TIMEOUT;
10287    }
10288
10289    @Override
10290    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10291        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10292                != PackageManager.PERMISSION_GRANTED) {
10293            throw new SecurityException("Requires permission "
10294                    + android.Manifest.permission.FILTER_EVENTS);
10295        }
10296        ProcessRecord proc;
10297        long timeout;
10298        synchronized (this) {
10299            synchronized (mPidsSelfLocked) {
10300                proc = mPidsSelfLocked.get(pid);
10301            }
10302            timeout = getInputDispatchingTimeoutLocked(proc);
10303        }
10304
10305        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10306            return -1;
10307        }
10308
10309        return timeout;
10310    }
10311
10312    /**
10313     * Handle input dispatching timeouts.
10314     * Returns whether input dispatching should be aborted or not.
10315     */
10316    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10317            final ActivityRecord activity, final ActivityRecord parent,
10318            final boolean aboveSystem, String reason) {
10319        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10320                != PackageManager.PERMISSION_GRANTED) {
10321            throw new SecurityException("Requires permission "
10322                    + android.Manifest.permission.FILTER_EVENTS);
10323        }
10324
10325        final String annotation;
10326        if (reason == null) {
10327            annotation = "Input dispatching timed out";
10328        } else {
10329            annotation = "Input dispatching timed out (" + reason + ")";
10330        }
10331
10332        if (proc != null) {
10333            synchronized (this) {
10334                if (proc.debugging) {
10335                    return false;
10336                }
10337
10338                if (mDidDexOpt) {
10339                    // Give more time since we were dexopting.
10340                    mDidDexOpt = false;
10341                    return false;
10342                }
10343
10344                if (proc.instrumentationClass != null) {
10345                    Bundle info = new Bundle();
10346                    info.putString("shortMsg", "keyDispatchingTimedOut");
10347                    info.putString("longMsg", annotation);
10348                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10349                    return true;
10350                }
10351            }
10352            mHandler.post(new Runnable() {
10353                @Override
10354                public void run() {
10355                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10356                }
10357            });
10358        }
10359
10360        return true;
10361    }
10362
10363    public Bundle getAssistContextExtras(int requestType) {
10364        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10365                "getAssistContextExtras()");
10366        PendingAssistExtras pae;
10367        Bundle extras = new Bundle();
10368        synchronized (this) {
10369            ActivityRecord activity = getFocusedStack().mResumedActivity;
10370            if (activity == null) {
10371                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10372                return null;
10373            }
10374            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10375            if (activity.app == null || activity.app.thread == null) {
10376                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10377                return extras;
10378            }
10379            if (activity.app.pid == Binder.getCallingPid()) {
10380                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10381                return extras;
10382            }
10383            pae = new PendingAssistExtras(activity);
10384            try {
10385                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10386                        requestType);
10387                mPendingAssistExtras.add(pae);
10388                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10389            } catch (RemoteException e) {
10390                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10391                return extras;
10392            }
10393        }
10394        synchronized (pae) {
10395            while (!pae.haveResult) {
10396                try {
10397                    pae.wait();
10398                } catch (InterruptedException e) {
10399                }
10400            }
10401            if (pae.result != null) {
10402                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10403            }
10404        }
10405        synchronized (this) {
10406            mPendingAssistExtras.remove(pae);
10407            mHandler.removeCallbacks(pae);
10408        }
10409        return extras;
10410    }
10411
10412    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10413        PendingAssistExtras pae = (PendingAssistExtras)token;
10414        synchronized (pae) {
10415            pae.result = extras;
10416            pae.haveResult = true;
10417            pae.notifyAll();
10418        }
10419    }
10420
10421    public void registerProcessObserver(IProcessObserver observer) {
10422        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10423                "registerProcessObserver()");
10424        synchronized (this) {
10425            mProcessObservers.register(observer);
10426        }
10427    }
10428
10429    @Override
10430    public void unregisterProcessObserver(IProcessObserver observer) {
10431        synchronized (this) {
10432            mProcessObservers.unregister(observer);
10433        }
10434    }
10435
10436    @Override
10437    public boolean convertFromTranslucent(IBinder token) {
10438        final long origId = Binder.clearCallingIdentity();
10439        try {
10440            synchronized (this) {
10441                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10442                if (r == null) {
10443                    return false;
10444                }
10445                final boolean translucentChanged = r.changeWindowTranslucency(true);
10446                if (translucentChanged) {
10447                    r.task.stack.releaseBackgroundResources();
10448                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10449                }
10450                mWindowManager.setAppFullscreen(token, true);
10451                return translucentChanged;
10452            }
10453        } finally {
10454            Binder.restoreCallingIdentity(origId);
10455        }
10456    }
10457
10458    @Override
10459    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10460        final long origId = Binder.clearCallingIdentity();
10461        try {
10462            synchronized (this) {
10463                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10464                if (r == null) {
10465                    return false;
10466                }
10467                int index = r.task.mActivities.lastIndexOf(r);
10468                if (index > 0) {
10469                    ActivityRecord under = r.task.mActivities.get(index - 1);
10470                    under.returningOptions = options;
10471                }
10472                final boolean translucentChanged = r.changeWindowTranslucency(false);
10473                if (translucentChanged) {
10474                    r.task.stack.convertToTranslucent(r);
10475                }
10476                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10477                mWindowManager.setAppFullscreen(token, false);
10478                return translucentChanged;
10479            }
10480        } finally {
10481            Binder.restoreCallingIdentity(origId);
10482        }
10483    }
10484
10485    @Override
10486    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10487        final long origId = Binder.clearCallingIdentity();
10488        try {
10489            synchronized (this) {
10490                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10491                if (r != null) {
10492                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10493                }
10494            }
10495            return false;
10496        } finally {
10497            Binder.restoreCallingIdentity(origId);
10498        }
10499    }
10500
10501    @Override
10502    public boolean isBackgroundVisibleBehind(IBinder token) {
10503        final long origId = Binder.clearCallingIdentity();
10504        try {
10505            synchronized (this) {
10506                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10507                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10508                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10509                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10510                return visible;
10511            }
10512        } finally {
10513            Binder.restoreCallingIdentity(origId);
10514        }
10515    }
10516
10517    @Override
10518    public ActivityOptions getActivityOptions(IBinder token) {
10519        final long origId = Binder.clearCallingIdentity();
10520        try {
10521            synchronized (this) {
10522                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10523                if (r != null) {
10524                    final ActivityOptions activityOptions = r.pendingOptions;
10525                    r.pendingOptions = null;
10526                    return activityOptions;
10527                }
10528                return null;
10529            }
10530        } finally {
10531            Binder.restoreCallingIdentity(origId);
10532        }
10533    }
10534
10535    @Override
10536    public void setImmersive(IBinder token, boolean immersive) {
10537        synchronized(this) {
10538            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10539            if (r == null) {
10540                throw new IllegalArgumentException();
10541            }
10542            r.immersive = immersive;
10543
10544            // update associated state if we're frontmost
10545            if (r == mFocusedActivity) {
10546                if (DEBUG_IMMERSIVE) {
10547                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10548                }
10549                applyUpdateLockStateLocked(r);
10550            }
10551        }
10552    }
10553
10554    @Override
10555    public boolean isImmersive(IBinder token) {
10556        synchronized (this) {
10557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10558            if (r == null) {
10559                throw new IllegalArgumentException();
10560            }
10561            return r.immersive;
10562        }
10563    }
10564
10565    public boolean isTopActivityImmersive() {
10566        enforceNotIsolatedCaller("startActivity");
10567        synchronized (this) {
10568            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10569            return (r != null) ? r.immersive : false;
10570        }
10571    }
10572
10573    @Override
10574    public boolean isTopOfTask(IBinder token) {
10575        synchronized (this) {
10576            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10577            if (r == null) {
10578                throw new IllegalArgumentException();
10579            }
10580            return r.task.getTopActivity() == r;
10581        }
10582    }
10583
10584    public final void enterSafeMode() {
10585        synchronized(this) {
10586            // It only makes sense to do this before the system is ready
10587            // and started launching other packages.
10588            if (!mSystemReady) {
10589                try {
10590                    AppGlobals.getPackageManager().enterSafeMode();
10591                } catch (RemoteException e) {
10592                }
10593            }
10594
10595            mSafeMode = true;
10596        }
10597    }
10598
10599    public final void showSafeModeOverlay() {
10600        View v = LayoutInflater.from(mContext).inflate(
10601                com.android.internal.R.layout.safe_mode, null);
10602        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10603        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10604        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10605        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10606        lp.gravity = Gravity.BOTTOM | Gravity.START;
10607        lp.format = v.getBackground().getOpacity();
10608        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10609                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10610        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10611        ((WindowManager)mContext.getSystemService(
10612                Context.WINDOW_SERVICE)).addView(v, lp);
10613    }
10614
10615    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10616        if (!(sender instanceof PendingIntentRecord)) {
10617            return;
10618        }
10619        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10620        synchronized (stats) {
10621            if (mBatteryStatsService.isOnBattery()) {
10622                mBatteryStatsService.enforceCallingPermission();
10623                PendingIntentRecord rec = (PendingIntentRecord)sender;
10624                int MY_UID = Binder.getCallingUid();
10625                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10626                BatteryStatsImpl.Uid.Pkg pkg =
10627                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10628                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10629                pkg.incWakeupsLocked();
10630            }
10631        }
10632    }
10633
10634    public boolean killPids(int[] pids, String pReason, boolean secure) {
10635        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10636            throw new SecurityException("killPids only available to the system");
10637        }
10638        String reason = (pReason == null) ? "Unknown" : pReason;
10639        // XXX Note: don't acquire main activity lock here, because the window
10640        // manager calls in with its locks held.
10641
10642        boolean killed = false;
10643        synchronized (mPidsSelfLocked) {
10644            int[] types = new int[pids.length];
10645            int worstType = 0;
10646            for (int i=0; i<pids.length; i++) {
10647                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10648                if (proc != null) {
10649                    int type = proc.setAdj;
10650                    types[i] = type;
10651                    if (type > worstType) {
10652                        worstType = type;
10653                    }
10654                }
10655            }
10656
10657            // If the worst oom_adj is somewhere in the cached proc LRU range,
10658            // then constrain it so we will kill all cached procs.
10659            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10660                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10661                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10662            }
10663
10664            // If this is not a secure call, don't let it kill processes that
10665            // are important.
10666            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10667                worstType = ProcessList.SERVICE_ADJ;
10668            }
10669
10670            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10671            for (int i=0; i<pids.length; i++) {
10672                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10673                if (proc == null) {
10674                    continue;
10675                }
10676                int adj = proc.setAdj;
10677                if (adj >= worstType && !proc.killedByAm) {
10678                    proc.kill(reason, true);
10679                    killed = true;
10680                }
10681            }
10682        }
10683        return killed;
10684    }
10685
10686    @Override
10687    public void killUid(int uid, String reason) {
10688        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10689            throw new SecurityException("killUid only available to the system");
10690        }
10691        synchronized (this) {
10692            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10693                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10694                    reason != null ? reason : "kill uid");
10695        }
10696    }
10697
10698    @Override
10699    public boolean killProcessesBelowForeground(String reason) {
10700        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10701            throw new SecurityException("killProcessesBelowForeground() only available to system");
10702        }
10703
10704        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10705    }
10706
10707    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10708        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10709            throw new SecurityException("killProcessesBelowAdj() only available to system");
10710        }
10711
10712        boolean killed = false;
10713        synchronized (mPidsSelfLocked) {
10714            final int size = mPidsSelfLocked.size();
10715            for (int i = 0; i < size; i++) {
10716                final int pid = mPidsSelfLocked.keyAt(i);
10717                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10718                if (proc == null) continue;
10719
10720                final int adj = proc.setAdj;
10721                if (adj > belowAdj && !proc.killedByAm) {
10722                    proc.kill(reason, true);
10723                    killed = true;
10724                }
10725            }
10726        }
10727        return killed;
10728    }
10729
10730    @Override
10731    public void hang(final IBinder who, boolean allowRestart) {
10732        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10733                != PackageManager.PERMISSION_GRANTED) {
10734            throw new SecurityException("Requires permission "
10735                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10736        }
10737
10738        final IBinder.DeathRecipient death = new DeathRecipient() {
10739            @Override
10740            public void binderDied() {
10741                synchronized (this) {
10742                    notifyAll();
10743                }
10744            }
10745        };
10746
10747        try {
10748            who.linkToDeath(death, 0);
10749        } catch (RemoteException e) {
10750            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10751            return;
10752        }
10753
10754        synchronized (this) {
10755            Watchdog.getInstance().setAllowRestart(allowRestart);
10756            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10757            synchronized (death) {
10758                while (who.isBinderAlive()) {
10759                    try {
10760                        death.wait();
10761                    } catch (InterruptedException e) {
10762                    }
10763                }
10764            }
10765            Watchdog.getInstance().setAllowRestart(true);
10766        }
10767    }
10768
10769    @Override
10770    public void restart() {
10771        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10772                != PackageManager.PERMISSION_GRANTED) {
10773            throw new SecurityException("Requires permission "
10774                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10775        }
10776
10777        Log.i(TAG, "Sending shutdown broadcast...");
10778
10779        BroadcastReceiver br = new BroadcastReceiver() {
10780            @Override public void onReceive(Context context, Intent intent) {
10781                // Now the broadcast is done, finish up the low-level shutdown.
10782                Log.i(TAG, "Shutting down activity manager...");
10783                shutdown(10000);
10784                Log.i(TAG, "Shutdown complete, restarting!");
10785                Process.killProcess(Process.myPid());
10786                System.exit(10);
10787            }
10788        };
10789
10790        // First send the high-level shut down broadcast.
10791        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10792        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10793        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10794        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10795        mContext.sendOrderedBroadcastAsUser(intent,
10796                UserHandle.ALL, null, br, mHandler, 0, null, null);
10797        */
10798        br.onReceive(mContext, intent);
10799    }
10800
10801    private long getLowRamTimeSinceIdle(long now) {
10802        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10803    }
10804
10805    @Override
10806    public void performIdleMaintenance() {
10807        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10808                != PackageManager.PERMISSION_GRANTED) {
10809            throw new SecurityException("Requires permission "
10810                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10811        }
10812
10813        synchronized (this) {
10814            final long now = SystemClock.uptimeMillis();
10815            final long timeSinceLastIdle = now - mLastIdleTime;
10816            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10817            mLastIdleTime = now;
10818            mLowRamTimeSinceLastIdle = 0;
10819            if (mLowRamStartTime != 0) {
10820                mLowRamStartTime = now;
10821            }
10822
10823            StringBuilder sb = new StringBuilder(128);
10824            sb.append("Idle maintenance over ");
10825            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10826            sb.append(" low RAM for ");
10827            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10828            Slog.i(TAG, sb.toString());
10829
10830            // If at least 1/3 of our time since the last idle period has been spent
10831            // with RAM low, then we want to kill processes.
10832            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10833
10834            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10835                ProcessRecord proc = mLruProcesses.get(i);
10836                if (proc.notCachedSinceIdle) {
10837                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10838                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10839                        if (doKilling && proc.initialIdlePss != 0
10840                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10841                            proc.kill("idle maint (pss " + proc.lastPss
10842                                    + " from " + proc.initialIdlePss + ")", true);
10843                        }
10844                    }
10845                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10846                    proc.notCachedSinceIdle = true;
10847                    proc.initialIdlePss = 0;
10848                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10849                            isSleeping(), now);
10850                }
10851            }
10852
10853            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10854            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10855        }
10856    }
10857
10858    private void retrieveSettings() {
10859        final ContentResolver resolver = mContext.getContentResolver();
10860        String debugApp = Settings.Global.getString(
10861            resolver, Settings.Global.DEBUG_APP);
10862        boolean waitForDebugger = Settings.Global.getInt(
10863            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10864        boolean alwaysFinishActivities = Settings.Global.getInt(
10865            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10866        boolean forceRtl = Settings.Global.getInt(
10867                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10868        // Transfer any global setting for forcing RTL layout, into a System Property
10869        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10870
10871        Configuration configuration = new Configuration();
10872        Settings.System.getConfiguration(resolver, configuration);
10873        if (forceRtl) {
10874            // This will take care of setting the correct layout direction flags
10875            configuration.setLayoutDirection(configuration.locale);
10876        }
10877
10878        synchronized (this) {
10879            mDebugApp = mOrigDebugApp = debugApp;
10880            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10881            mAlwaysFinishActivities = alwaysFinishActivities;
10882            // This happens before any activities are started, so we can
10883            // change mConfiguration in-place.
10884            updateConfigurationLocked(configuration, null, false, true);
10885            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10886        }
10887    }
10888
10889    /** Loads resources after the current configuration has been set. */
10890    private void loadResourcesOnSystemReady() {
10891        final Resources res = mContext.getResources();
10892        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10893        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10894        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10895    }
10896
10897    public boolean testIsSystemReady() {
10898        // no need to synchronize(this) just to read & return the value
10899        return mSystemReady;
10900    }
10901
10902    private static File getCalledPreBootReceiversFile() {
10903        File dataDir = Environment.getDataDirectory();
10904        File systemDir = new File(dataDir, "system");
10905        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10906        return fname;
10907    }
10908
10909    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10910        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10911        File file = getCalledPreBootReceiversFile();
10912        FileInputStream fis = null;
10913        try {
10914            fis = new FileInputStream(file);
10915            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10916            int fvers = dis.readInt();
10917            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10918                String vers = dis.readUTF();
10919                String codename = dis.readUTF();
10920                String build = dis.readUTF();
10921                if (android.os.Build.VERSION.RELEASE.equals(vers)
10922                        && android.os.Build.VERSION.CODENAME.equals(codename)
10923                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10924                    int num = dis.readInt();
10925                    while (num > 0) {
10926                        num--;
10927                        String pkg = dis.readUTF();
10928                        String cls = dis.readUTF();
10929                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10930                    }
10931                }
10932            }
10933        } catch (FileNotFoundException e) {
10934        } catch (IOException e) {
10935            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10936        } finally {
10937            if (fis != null) {
10938                try {
10939                    fis.close();
10940                } catch (IOException e) {
10941                }
10942            }
10943        }
10944        return lastDoneReceivers;
10945    }
10946
10947    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10948        File file = getCalledPreBootReceiversFile();
10949        FileOutputStream fos = null;
10950        DataOutputStream dos = null;
10951        try {
10952            fos = new FileOutputStream(file);
10953            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10954            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10955            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10956            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10957            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10958            dos.writeInt(list.size());
10959            for (int i=0; i<list.size(); i++) {
10960                dos.writeUTF(list.get(i).getPackageName());
10961                dos.writeUTF(list.get(i).getClassName());
10962            }
10963        } catch (IOException e) {
10964            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10965            file.delete();
10966        } finally {
10967            FileUtils.sync(fos);
10968            if (dos != null) {
10969                try {
10970                    dos.close();
10971                } catch (IOException e) {
10972                    // TODO Auto-generated catch block
10973                    e.printStackTrace();
10974                }
10975            }
10976        }
10977    }
10978
10979    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10980            ArrayList<ComponentName> doneReceivers, int userId) {
10981        boolean waitingUpdate = false;
10982        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10983        List<ResolveInfo> ris = null;
10984        try {
10985            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10986                    intent, null, 0, userId);
10987        } catch (RemoteException e) {
10988        }
10989        if (ris != null) {
10990            for (int i=ris.size()-1; i>=0; i--) {
10991                if ((ris.get(i).activityInfo.applicationInfo.flags
10992                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10993                    ris.remove(i);
10994                }
10995            }
10996            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10997
10998            // For User 0, load the version number. When delivering to a new user, deliver
10999            // to all receivers.
11000            if (userId == UserHandle.USER_OWNER) {
11001                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
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                    if (lastDoneReceivers.contains(comp)) {
11006                        // We already did the pre boot receiver for this app with the current
11007                        // platform version, so don't do it again...
11008                        ris.remove(i);
11009                        i--;
11010                        // ...however, do keep it as one that has been done, so we don't
11011                        // forget about it when rewriting the file of last done receivers.
11012                        doneReceivers.add(comp);
11013                    }
11014                }
11015            }
11016
11017            // If primary user, send broadcast to all available users, else just to userId
11018            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11019                    : new int[] { userId };
11020            for (int i = 0; i < ris.size(); i++) {
11021                ActivityInfo ai = ris.get(i).activityInfo;
11022                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11023                doneReceivers.add(comp);
11024                intent.setComponent(comp);
11025                for (int j=0; j<users.length; j++) {
11026                    IIntentReceiver finisher = null;
11027                    // On last receiver and user, set up a completion callback
11028                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11029                        finisher = new IIntentReceiver.Stub() {
11030                            public void performReceive(Intent intent, int resultCode,
11031                                    String data, Bundle extras, boolean ordered,
11032                                    boolean sticky, int sendingUser) {
11033                                // The raw IIntentReceiver interface is called
11034                                // with the AM lock held, so redispatch to
11035                                // execute our code without the lock.
11036                                mHandler.post(onFinishCallback);
11037                            }
11038                        };
11039                    }
11040                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11041                            + " for user " + users[j]);
11042                    broadcastIntentLocked(null, null, intent, null, finisher,
11043                            0, null, null, null, AppOpsManager.OP_NONE,
11044                            true, false, MY_PID, Process.SYSTEM_UID,
11045                            users[j]);
11046                    if (finisher != null) {
11047                        waitingUpdate = true;
11048                    }
11049                }
11050            }
11051        }
11052
11053        return waitingUpdate;
11054    }
11055
11056    public void systemReady(final Runnable goingCallback) {
11057        synchronized(this) {
11058            if (mSystemReady) {
11059                // If we're done calling all the receivers, run the next "boot phase" passed in
11060                // by the SystemServer
11061                if (goingCallback != null) {
11062                    goingCallback.run();
11063                }
11064                return;
11065            }
11066
11067            // Make sure we have the current profile info, since it is needed for
11068            // security checks.
11069            updateCurrentProfileIdsLocked();
11070
11071            if (mRecentTasks == null) {
11072                mRecentTasks = mTaskPersister.restoreTasksLocked();
11073                if (!mRecentTasks.isEmpty()) {
11074                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11075                }
11076                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11077                mTaskPersister.startPersisting();
11078            }
11079
11080            // Check to see if there are any update receivers to run.
11081            if (!mDidUpdate) {
11082                if (mWaitingUpdate) {
11083                    return;
11084                }
11085                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11086                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11087                    public void run() {
11088                        synchronized (ActivityManagerService.this) {
11089                            mDidUpdate = true;
11090                        }
11091                        writeLastDonePreBootReceivers(doneReceivers);
11092                        showBootMessage(mContext.getText(
11093                                R.string.android_upgrading_complete),
11094                                false);
11095                        systemReady(goingCallback);
11096                    }
11097                }, doneReceivers, UserHandle.USER_OWNER);
11098
11099                if (mWaitingUpdate) {
11100                    return;
11101                }
11102                mDidUpdate = true;
11103            }
11104
11105            mAppOpsService.systemReady();
11106            mSystemReady = true;
11107        }
11108
11109        ArrayList<ProcessRecord> procsToKill = null;
11110        synchronized(mPidsSelfLocked) {
11111            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11112                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11113                if (!isAllowedWhileBooting(proc.info)){
11114                    if (procsToKill == null) {
11115                        procsToKill = new ArrayList<ProcessRecord>();
11116                    }
11117                    procsToKill.add(proc);
11118                }
11119            }
11120        }
11121
11122        synchronized(this) {
11123            if (procsToKill != null) {
11124                for (int i=procsToKill.size()-1; i>=0; i--) {
11125                    ProcessRecord proc = procsToKill.get(i);
11126                    Slog.i(TAG, "Removing system update proc: " + proc);
11127                    removeProcessLocked(proc, true, false, "system update done");
11128                }
11129            }
11130
11131            // Now that we have cleaned up any update processes, we
11132            // are ready to start launching real processes and know that
11133            // we won't trample on them any more.
11134            mProcessesReady = true;
11135        }
11136
11137        Slog.i(TAG, "System now ready");
11138        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11139            SystemClock.uptimeMillis());
11140
11141        synchronized(this) {
11142            // Make sure we have no pre-ready processes sitting around.
11143
11144            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11145                ResolveInfo ri = mContext.getPackageManager()
11146                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11147                                STOCK_PM_FLAGS);
11148                CharSequence errorMsg = null;
11149                if (ri != null) {
11150                    ActivityInfo ai = ri.activityInfo;
11151                    ApplicationInfo app = ai.applicationInfo;
11152                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11153                        mTopAction = Intent.ACTION_FACTORY_TEST;
11154                        mTopData = null;
11155                        mTopComponent = new ComponentName(app.packageName,
11156                                ai.name);
11157                    } else {
11158                        errorMsg = mContext.getResources().getText(
11159                                com.android.internal.R.string.factorytest_not_system);
11160                    }
11161                } else {
11162                    errorMsg = mContext.getResources().getText(
11163                            com.android.internal.R.string.factorytest_no_action);
11164                }
11165                if (errorMsg != null) {
11166                    mTopAction = null;
11167                    mTopData = null;
11168                    mTopComponent = null;
11169                    Message msg = Message.obtain();
11170                    msg.what = SHOW_FACTORY_ERROR_MSG;
11171                    msg.getData().putCharSequence("msg", errorMsg);
11172                    mHandler.sendMessage(msg);
11173                }
11174            }
11175        }
11176
11177        retrieveSettings();
11178        loadResourcesOnSystemReady();
11179
11180        synchronized (this) {
11181            readGrantedUriPermissionsLocked();
11182        }
11183
11184        if (goingCallback != null) goingCallback.run();
11185
11186        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11187                Integer.toString(mCurrentUserId), mCurrentUserId);
11188        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11189                Integer.toString(mCurrentUserId), mCurrentUserId);
11190        mSystemServiceManager.startUser(mCurrentUserId);
11191
11192        synchronized (this) {
11193            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11194                try {
11195                    List apps = AppGlobals.getPackageManager().
11196                        getPersistentApplications(STOCK_PM_FLAGS);
11197                    if (apps != null) {
11198                        int N = apps.size();
11199                        int i;
11200                        for (i=0; i<N; i++) {
11201                            ApplicationInfo info
11202                                = (ApplicationInfo)apps.get(i);
11203                            if (info != null &&
11204                                    !info.packageName.equals("android")) {
11205                                addAppLocked(info, false, null /* ABI override */);
11206                            }
11207                        }
11208                    }
11209                } catch (RemoteException ex) {
11210                    // pm is in same process, this will never happen.
11211                }
11212            }
11213
11214            // Start up initial activity.
11215            mBooting = true;
11216
11217            try {
11218                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11219                    Message msg = Message.obtain();
11220                    msg.what = SHOW_UID_ERROR_MSG;
11221                    mHandler.sendMessage(msg);
11222                }
11223            } catch (RemoteException e) {
11224            }
11225
11226            long ident = Binder.clearCallingIdentity();
11227            try {
11228                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11229                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11230                        | Intent.FLAG_RECEIVER_FOREGROUND);
11231                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11232                broadcastIntentLocked(null, null, intent,
11233                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11234                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11235                intent = new Intent(Intent.ACTION_USER_STARTING);
11236                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11237                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11238                broadcastIntentLocked(null, null, intent,
11239                        null, new IIntentReceiver.Stub() {
11240                            @Override
11241                            public void performReceive(Intent intent, int resultCode, String data,
11242                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11243                                    throws RemoteException {
11244                            }
11245                        }, 0, null, null,
11246                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11247                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11248            } catch (Throwable t) {
11249                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11250            } finally {
11251                Binder.restoreCallingIdentity(ident);
11252            }
11253            mStackSupervisor.resumeTopActivitiesLocked();
11254            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11255        }
11256    }
11257
11258    private boolean makeAppCrashingLocked(ProcessRecord app,
11259            String shortMsg, String longMsg, String stackTrace) {
11260        app.crashing = true;
11261        app.crashingReport = generateProcessError(app,
11262                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11263        startAppProblemLocked(app);
11264        app.stopFreezingAllLocked();
11265        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11266    }
11267
11268    private void makeAppNotRespondingLocked(ProcessRecord app,
11269            String activity, String shortMsg, String longMsg) {
11270        app.notResponding = true;
11271        app.notRespondingReport = generateProcessError(app,
11272                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11273                activity, shortMsg, longMsg, null);
11274        startAppProblemLocked(app);
11275        app.stopFreezingAllLocked();
11276    }
11277
11278    /**
11279     * Generate a process error record, suitable for attachment to a ProcessRecord.
11280     *
11281     * @param app The ProcessRecord in which the error occurred.
11282     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11283     *                      ActivityManager.AppErrorStateInfo
11284     * @param activity The activity associated with the crash, if known.
11285     * @param shortMsg Short message describing the crash.
11286     * @param longMsg Long message describing the crash.
11287     * @param stackTrace Full crash stack trace, may be null.
11288     *
11289     * @return Returns a fully-formed AppErrorStateInfo record.
11290     */
11291    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11292            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11293        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11294
11295        report.condition = condition;
11296        report.processName = app.processName;
11297        report.pid = app.pid;
11298        report.uid = app.info.uid;
11299        report.tag = activity;
11300        report.shortMsg = shortMsg;
11301        report.longMsg = longMsg;
11302        report.stackTrace = stackTrace;
11303
11304        return report;
11305    }
11306
11307    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11308        synchronized (this) {
11309            app.crashing = false;
11310            app.crashingReport = null;
11311            app.notResponding = false;
11312            app.notRespondingReport = null;
11313            if (app.anrDialog == fromDialog) {
11314                app.anrDialog = null;
11315            }
11316            if (app.waitDialog == fromDialog) {
11317                app.waitDialog = null;
11318            }
11319            if (app.pid > 0 && app.pid != MY_PID) {
11320                handleAppCrashLocked(app, null, null, null);
11321                app.kill("user request after error", true);
11322            }
11323        }
11324    }
11325
11326    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11327            String stackTrace) {
11328        long now = SystemClock.uptimeMillis();
11329
11330        Long crashTime;
11331        if (!app.isolated) {
11332            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11333        } else {
11334            crashTime = null;
11335        }
11336        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11337            // This process loses!
11338            Slog.w(TAG, "Process " + app.info.processName
11339                    + " has crashed too many times: killing!");
11340            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11341                    app.userId, app.info.processName, app.uid);
11342            mStackSupervisor.handleAppCrashLocked(app);
11343            if (!app.persistent) {
11344                // We don't want to start this process again until the user
11345                // explicitly does so...  but for persistent process, we really
11346                // need to keep it running.  If a persistent process is actually
11347                // repeatedly crashing, then badness for everyone.
11348                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11349                        app.info.processName);
11350                if (!app.isolated) {
11351                    // XXX We don't have a way to mark isolated processes
11352                    // as bad, since they don't have a peristent identity.
11353                    mBadProcesses.put(app.info.processName, app.uid,
11354                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11355                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11356                }
11357                app.bad = true;
11358                app.removed = true;
11359                // Don't let services in this process be restarted and potentially
11360                // annoy the user repeatedly.  Unless it is persistent, since those
11361                // processes run critical code.
11362                removeProcessLocked(app, false, false, "crash");
11363                mStackSupervisor.resumeTopActivitiesLocked();
11364                return false;
11365            }
11366            mStackSupervisor.resumeTopActivitiesLocked();
11367        } else {
11368            mStackSupervisor.finishTopRunningActivityLocked(app);
11369        }
11370
11371        // Bump up the crash count of any services currently running in the proc.
11372        for (int i=app.services.size()-1; i>=0; i--) {
11373            // Any services running in the application need to be placed
11374            // back in the pending list.
11375            ServiceRecord sr = app.services.valueAt(i);
11376            sr.crashCount++;
11377        }
11378
11379        // If the crashing process is what we consider to be the "home process" and it has been
11380        // replaced by a third-party app, clear the package preferred activities from packages
11381        // with a home activity running in the process to prevent a repeatedly crashing app
11382        // from blocking the user to manually clear the list.
11383        final ArrayList<ActivityRecord> activities = app.activities;
11384        if (app == mHomeProcess && activities.size() > 0
11385                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11386            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11387                final ActivityRecord r = activities.get(activityNdx);
11388                if (r.isHomeActivity()) {
11389                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11390                    try {
11391                        ActivityThread.getPackageManager()
11392                                .clearPackagePreferredActivities(r.packageName);
11393                    } catch (RemoteException c) {
11394                        // pm is in same process, this will never happen.
11395                    }
11396                }
11397            }
11398        }
11399
11400        if (!app.isolated) {
11401            // XXX Can't keep track of crash times for isolated processes,
11402            // because they don't have a perisistent identity.
11403            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11404        }
11405
11406        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11407        return true;
11408    }
11409
11410    void startAppProblemLocked(ProcessRecord app) {
11411        // If this app is not running under the current user, then we
11412        // can't give it a report button because that would require
11413        // launching the report UI under a different user.
11414        app.errorReportReceiver = null;
11415
11416        for (int userId : mCurrentProfileIds) {
11417            if (app.userId == userId) {
11418                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11419                        mContext, app.info.packageName, app.info.flags);
11420            }
11421        }
11422        skipCurrentReceiverLocked(app);
11423    }
11424
11425    void skipCurrentReceiverLocked(ProcessRecord app) {
11426        for (BroadcastQueue queue : mBroadcastQueues) {
11427            queue.skipCurrentReceiverLocked(app);
11428        }
11429    }
11430
11431    /**
11432     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11433     * The application process will exit immediately after this call returns.
11434     * @param app object of the crashing app, null for the system server
11435     * @param crashInfo describing the exception
11436     */
11437    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11438        ProcessRecord r = findAppProcess(app, "Crash");
11439        final String processName = app == null ? "system_server"
11440                : (r == null ? "unknown" : r.processName);
11441
11442        handleApplicationCrashInner("crash", r, processName, crashInfo);
11443    }
11444
11445    /* Native crash reporting uses this inner version because it needs to be somewhat
11446     * decoupled from the AM-managed cleanup lifecycle
11447     */
11448    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11449            ApplicationErrorReport.CrashInfo crashInfo) {
11450        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11451                UserHandle.getUserId(Binder.getCallingUid()), processName,
11452                r == null ? -1 : r.info.flags,
11453                crashInfo.exceptionClassName,
11454                crashInfo.exceptionMessage,
11455                crashInfo.throwFileName,
11456                crashInfo.throwLineNumber);
11457
11458        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11459
11460        crashApplication(r, crashInfo);
11461    }
11462
11463    public void handleApplicationStrictModeViolation(
11464            IBinder app,
11465            int violationMask,
11466            StrictMode.ViolationInfo info) {
11467        ProcessRecord r = findAppProcess(app, "StrictMode");
11468        if (r == null) {
11469            return;
11470        }
11471
11472        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11473            Integer stackFingerprint = info.hashCode();
11474            boolean logIt = true;
11475            synchronized (mAlreadyLoggedViolatedStacks) {
11476                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11477                    logIt = false;
11478                    // TODO: sub-sample into EventLog for these, with
11479                    // the info.durationMillis?  Then we'd get
11480                    // the relative pain numbers, without logging all
11481                    // the stack traces repeatedly.  We'd want to do
11482                    // likewise in the client code, which also does
11483                    // dup suppression, before the Binder call.
11484                } else {
11485                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11486                        mAlreadyLoggedViolatedStacks.clear();
11487                    }
11488                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11489                }
11490            }
11491            if (logIt) {
11492                logStrictModeViolationToDropBox(r, info);
11493            }
11494        }
11495
11496        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11497            AppErrorResult result = new AppErrorResult();
11498            synchronized (this) {
11499                final long origId = Binder.clearCallingIdentity();
11500
11501                Message msg = Message.obtain();
11502                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11503                HashMap<String, Object> data = new HashMap<String, Object>();
11504                data.put("result", result);
11505                data.put("app", r);
11506                data.put("violationMask", violationMask);
11507                data.put("info", info);
11508                msg.obj = data;
11509                mHandler.sendMessage(msg);
11510
11511                Binder.restoreCallingIdentity(origId);
11512            }
11513            int res = result.get();
11514            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11515        }
11516    }
11517
11518    // Depending on the policy in effect, there could be a bunch of
11519    // these in quick succession so we try to batch these together to
11520    // minimize disk writes, number of dropbox entries, and maximize
11521    // compression, by having more fewer, larger records.
11522    private void logStrictModeViolationToDropBox(
11523            ProcessRecord process,
11524            StrictMode.ViolationInfo info) {
11525        if (info == null) {
11526            return;
11527        }
11528        final boolean isSystemApp = process == null ||
11529                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11530                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11531        final String processName = process == null ? "unknown" : process.processName;
11532        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11533        final DropBoxManager dbox = (DropBoxManager)
11534                mContext.getSystemService(Context.DROPBOX_SERVICE);
11535
11536        // Exit early if the dropbox isn't configured to accept this report type.
11537        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11538
11539        boolean bufferWasEmpty;
11540        boolean needsFlush;
11541        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11542        synchronized (sb) {
11543            bufferWasEmpty = sb.length() == 0;
11544            appendDropBoxProcessHeaders(process, processName, sb);
11545            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11546            sb.append("System-App: ").append(isSystemApp).append("\n");
11547            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11548            if (info.violationNumThisLoop != 0) {
11549                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11550            }
11551            if (info.numAnimationsRunning != 0) {
11552                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11553            }
11554            if (info.broadcastIntentAction != null) {
11555                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11556            }
11557            if (info.durationMillis != -1) {
11558                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11559            }
11560            if (info.numInstances != -1) {
11561                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11562            }
11563            if (info.tags != null) {
11564                for (String tag : info.tags) {
11565                    sb.append("Span-Tag: ").append(tag).append("\n");
11566                }
11567            }
11568            sb.append("\n");
11569            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11570                sb.append(info.crashInfo.stackTrace);
11571            }
11572            sb.append("\n");
11573
11574            // Only buffer up to ~64k.  Various logging bits truncate
11575            // things at 128k.
11576            needsFlush = (sb.length() > 64 * 1024);
11577        }
11578
11579        // Flush immediately if the buffer's grown too large, or this
11580        // is a non-system app.  Non-system apps are isolated with a
11581        // different tag & policy and not batched.
11582        //
11583        // Batching is useful during internal testing with
11584        // StrictMode settings turned up high.  Without batching,
11585        // thousands of separate files could be created on boot.
11586        if (!isSystemApp || needsFlush) {
11587            new Thread("Error dump: " + dropboxTag) {
11588                @Override
11589                public void run() {
11590                    String report;
11591                    synchronized (sb) {
11592                        report = sb.toString();
11593                        sb.delete(0, sb.length());
11594                        sb.trimToSize();
11595                    }
11596                    if (report.length() != 0) {
11597                        dbox.addText(dropboxTag, report);
11598                    }
11599                }
11600            }.start();
11601            return;
11602        }
11603
11604        // System app batching:
11605        if (!bufferWasEmpty) {
11606            // An existing dropbox-writing thread is outstanding, so
11607            // we don't need to start it up.  The existing thread will
11608            // catch the buffer appends we just did.
11609            return;
11610        }
11611
11612        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11613        // (After this point, we shouldn't access AMS internal data structures.)
11614        new Thread("Error dump: " + dropboxTag) {
11615            @Override
11616            public void run() {
11617                // 5 second sleep to let stacks arrive and be batched together
11618                try {
11619                    Thread.sleep(5000);  // 5 seconds
11620                } catch (InterruptedException e) {}
11621
11622                String errorReport;
11623                synchronized (mStrictModeBuffer) {
11624                    errorReport = mStrictModeBuffer.toString();
11625                    if (errorReport.length() == 0) {
11626                        return;
11627                    }
11628                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11629                    mStrictModeBuffer.trimToSize();
11630                }
11631                dbox.addText(dropboxTag, errorReport);
11632            }
11633        }.start();
11634    }
11635
11636    /**
11637     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11638     * @param app object of the crashing app, null for the system server
11639     * @param tag reported by the caller
11640     * @param system whether this wtf is coming from the system
11641     * @param crashInfo describing the context of the error
11642     * @return true if the process should exit immediately (WTF is fatal)
11643     */
11644    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11645            final ApplicationErrorReport.CrashInfo crashInfo) {
11646        final ProcessRecord r = findAppProcess(app, "WTF");
11647        final String processName = app == null ? "system_server"
11648                : (r == null ? "unknown" : r.processName);
11649
11650        EventLog.writeEvent(EventLogTags.AM_WTF,
11651                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11652                processName,
11653                r == null ? -1 : r.info.flags,
11654                tag, crashInfo.exceptionMessage);
11655
11656        if (system) {
11657            // If this is coming from the system, we could very well have low-level
11658            // system locks held, so we want to do this all asynchronously.  And we
11659            // never want this to become fatal, so there is that too.
11660            mHandler.post(new Runnable() {
11661                @Override public void run() {
11662                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11663                            crashInfo);
11664                }
11665            });
11666            return false;
11667        }
11668
11669        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11670
11671        if (r != null && r.pid != Process.myPid() &&
11672                Settings.Global.getInt(mContext.getContentResolver(),
11673                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11674            crashApplication(r, crashInfo);
11675            return true;
11676        } else {
11677            return false;
11678        }
11679    }
11680
11681    /**
11682     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11683     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11684     */
11685    private ProcessRecord findAppProcess(IBinder app, String reason) {
11686        if (app == null) {
11687            return null;
11688        }
11689
11690        synchronized (this) {
11691            final int NP = mProcessNames.getMap().size();
11692            for (int ip=0; ip<NP; ip++) {
11693                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11694                final int NA = apps.size();
11695                for (int ia=0; ia<NA; ia++) {
11696                    ProcessRecord p = apps.valueAt(ia);
11697                    if (p.thread != null && p.thread.asBinder() == app) {
11698                        return p;
11699                    }
11700                }
11701            }
11702
11703            Slog.w(TAG, "Can't find mystery application for " + reason
11704                    + " from pid=" + Binder.getCallingPid()
11705                    + " uid=" + Binder.getCallingUid() + ": " + app);
11706            return null;
11707        }
11708    }
11709
11710    /**
11711     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11712     * to append various headers to the dropbox log text.
11713     */
11714    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11715            StringBuilder sb) {
11716        // Watchdog thread ends up invoking this function (with
11717        // a null ProcessRecord) to add the stack file to dropbox.
11718        // Do not acquire a lock on this (am) in such cases, as it
11719        // could cause a potential deadlock, if and when watchdog
11720        // is invoked due to unavailability of lock on am and it
11721        // would prevent watchdog from killing system_server.
11722        if (process == null) {
11723            sb.append("Process: ").append(processName).append("\n");
11724            return;
11725        }
11726        // Note: ProcessRecord 'process' is guarded by the service
11727        // instance.  (notably process.pkgList, which could otherwise change
11728        // concurrently during execution of this method)
11729        synchronized (this) {
11730            sb.append("Process: ").append(processName).append("\n");
11731            int flags = process.info.flags;
11732            IPackageManager pm = AppGlobals.getPackageManager();
11733            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11734            for (int ip=0; ip<process.pkgList.size(); ip++) {
11735                String pkg = process.pkgList.keyAt(ip);
11736                sb.append("Package: ").append(pkg);
11737                try {
11738                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11739                    if (pi != null) {
11740                        sb.append(" v").append(pi.versionCode);
11741                        if (pi.versionName != null) {
11742                            sb.append(" (").append(pi.versionName).append(")");
11743                        }
11744                    }
11745                } catch (RemoteException e) {
11746                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11747                }
11748                sb.append("\n");
11749            }
11750        }
11751    }
11752
11753    private static String processClass(ProcessRecord process) {
11754        if (process == null || process.pid == MY_PID) {
11755            return "system_server";
11756        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11757            return "system_app";
11758        } else {
11759            return "data_app";
11760        }
11761    }
11762
11763    /**
11764     * Write a description of an error (crash, WTF, ANR) to the drop box.
11765     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11766     * @param process which caused the error, null means the system server
11767     * @param activity which triggered the error, null if unknown
11768     * @param parent activity related to the error, null if unknown
11769     * @param subject line related to the error, null if absent
11770     * @param report in long form describing the error, null if absent
11771     * @param logFile to include in the report, null if none
11772     * @param crashInfo giving an application stack trace, null if absent
11773     */
11774    public void addErrorToDropBox(String eventType,
11775            ProcessRecord process, String processName, ActivityRecord activity,
11776            ActivityRecord parent, String subject,
11777            final String report, final File logFile,
11778            final ApplicationErrorReport.CrashInfo crashInfo) {
11779        // NOTE -- this must never acquire the ActivityManagerService lock,
11780        // otherwise the watchdog may be prevented from resetting the system.
11781
11782        final String dropboxTag = processClass(process) + "_" + eventType;
11783        final DropBoxManager dbox = (DropBoxManager)
11784                mContext.getSystemService(Context.DROPBOX_SERVICE);
11785
11786        // Exit early if the dropbox isn't configured to accept this report type.
11787        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11788
11789        final StringBuilder sb = new StringBuilder(1024);
11790        appendDropBoxProcessHeaders(process, processName, sb);
11791        if (activity != null) {
11792            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11793        }
11794        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11795            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11796        }
11797        if (parent != null && parent != activity) {
11798            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11799        }
11800        if (subject != null) {
11801            sb.append("Subject: ").append(subject).append("\n");
11802        }
11803        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11804        if (Debug.isDebuggerConnected()) {
11805            sb.append("Debugger: Connected\n");
11806        }
11807        sb.append("\n");
11808
11809        // Do the rest in a worker thread to avoid blocking the caller on I/O
11810        // (After this point, we shouldn't access AMS internal data structures.)
11811        Thread worker = new Thread("Error dump: " + dropboxTag) {
11812            @Override
11813            public void run() {
11814                if (report != null) {
11815                    sb.append(report);
11816                }
11817                if (logFile != null) {
11818                    try {
11819                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11820                                    "\n\n[[TRUNCATED]]"));
11821                    } catch (IOException e) {
11822                        Slog.e(TAG, "Error reading " + logFile, e);
11823                    }
11824                }
11825                if (crashInfo != null && crashInfo.stackTrace != null) {
11826                    sb.append(crashInfo.stackTrace);
11827                }
11828
11829                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11830                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11831                if (lines > 0) {
11832                    sb.append("\n");
11833
11834                    // Merge several logcat streams, and take the last N lines
11835                    InputStreamReader input = null;
11836                    try {
11837                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11838                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11839                                "-b", "crash",
11840                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11841
11842                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11843                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11844                        input = new InputStreamReader(logcat.getInputStream());
11845
11846                        int num;
11847                        char[] buf = new char[8192];
11848                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11849                    } catch (IOException e) {
11850                        Slog.e(TAG, "Error running logcat", e);
11851                    } finally {
11852                        if (input != null) try { input.close(); } catch (IOException e) {}
11853                    }
11854                }
11855
11856                dbox.addText(dropboxTag, sb.toString());
11857            }
11858        };
11859
11860        if (process == null) {
11861            // If process is null, we are being called from some internal code
11862            // and may be about to die -- run this synchronously.
11863            worker.run();
11864        } else {
11865            worker.start();
11866        }
11867    }
11868
11869    /**
11870     * Bring up the "unexpected error" dialog box for a crashing app.
11871     * Deal with edge cases (intercepts from instrumented applications,
11872     * ActivityController, error intent receivers, that sort of thing).
11873     * @param r the application crashing
11874     * @param crashInfo describing the failure
11875     */
11876    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11877        long timeMillis = System.currentTimeMillis();
11878        String shortMsg = crashInfo.exceptionClassName;
11879        String longMsg = crashInfo.exceptionMessage;
11880        String stackTrace = crashInfo.stackTrace;
11881        if (shortMsg != null && longMsg != null) {
11882            longMsg = shortMsg + ": " + longMsg;
11883        } else if (shortMsg != null) {
11884            longMsg = shortMsg;
11885        }
11886
11887        AppErrorResult result = new AppErrorResult();
11888        synchronized (this) {
11889            if (mController != null) {
11890                try {
11891                    String name = r != null ? r.processName : null;
11892                    int pid = r != null ? r.pid : Binder.getCallingPid();
11893                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11894                    if (!mController.appCrashed(name, pid,
11895                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11896                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11897                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11898                            Slog.w(TAG, "Skip killing native crashed app " + name
11899                                    + "(" + pid + ") during testing");
11900                        } else {
11901                            Slog.w(TAG, "Force-killing crashed app " + name
11902                                    + " at watcher's request");
11903                            if (r != null) {
11904                                r.kill("crash", true);
11905                            } else {
11906                                // Huh.
11907                                Process.killProcess(pid);
11908                                Process.killProcessGroup(uid, pid);
11909                            }
11910                        }
11911                        return;
11912                    }
11913                } catch (RemoteException e) {
11914                    mController = null;
11915                    Watchdog.getInstance().setActivityController(null);
11916                }
11917            }
11918
11919            final long origId = Binder.clearCallingIdentity();
11920
11921            // If this process is running instrumentation, finish it.
11922            if (r != null && r.instrumentationClass != null) {
11923                Slog.w(TAG, "Error in app " + r.processName
11924                      + " running instrumentation " + r.instrumentationClass + ":");
11925                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11926                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11927                Bundle info = new Bundle();
11928                info.putString("shortMsg", shortMsg);
11929                info.putString("longMsg", longMsg);
11930                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11931                Binder.restoreCallingIdentity(origId);
11932                return;
11933            }
11934
11935            // If we can't identify the process or it's already exceeded its crash quota,
11936            // quit right away without showing a crash dialog.
11937            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11938                Binder.restoreCallingIdentity(origId);
11939                return;
11940            }
11941
11942            Message msg = Message.obtain();
11943            msg.what = SHOW_ERROR_MSG;
11944            HashMap data = new HashMap();
11945            data.put("result", result);
11946            data.put("app", r);
11947            msg.obj = data;
11948            mHandler.sendMessage(msg);
11949
11950            Binder.restoreCallingIdentity(origId);
11951        }
11952
11953        int res = result.get();
11954
11955        Intent appErrorIntent = null;
11956        synchronized (this) {
11957            if (r != null && !r.isolated) {
11958                // XXX Can't keep track of crash time for isolated processes,
11959                // since they don't have a persistent identity.
11960                mProcessCrashTimes.put(r.info.processName, r.uid,
11961                        SystemClock.uptimeMillis());
11962            }
11963            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11964                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11965            }
11966        }
11967
11968        if (appErrorIntent != null) {
11969            try {
11970                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11971            } catch (ActivityNotFoundException e) {
11972                Slog.w(TAG, "bug report receiver dissappeared", e);
11973            }
11974        }
11975    }
11976
11977    Intent createAppErrorIntentLocked(ProcessRecord r,
11978            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11979        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11980        if (report == null) {
11981            return null;
11982        }
11983        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11984        result.setComponent(r.errorReportReceiver);
11985        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11986        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11987        return result;
11988    }
11989
11990    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11991            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11992        if (r.errorReportReceiver == null) {
11993            return null;
11994        }
11995
11996        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11997            return null;
11998        }
11999
12000        ApplicationErrorReport report = new ApplicationErrorReport();
12001        report.packageName = r.info.packageName;
12002        report.installerPackageName = r.errorReportReceiver.getPackageName();
12003        report.processName = r.processName;
12004        report.time = timeMillis;
12005        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12006
12007        if (r.crashing || r.forceCrashReport) {
12008            report.type = ApplicationErrorReport.TYPE_CRASH;
12009            report.crashInfo = crashInfo;
12010        } else if (r.notResponding) {
12011            report.type = ApplicationErrorReport.TYPE_ANR;
12012            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12013
12014            report.anrInfo.activity = r.notRespondingReport.tag;
12015            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12016            report.anrInfo.info = r.notRespondingReport.longMsg;
12017        }
12018
12019        return report;
12020    }
12021
12022    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12023        enforceNotIsolatedCaller("getProcessesInErrorState");
12024        // assume our apps are happy - lazy create the list
12025        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12026
12027        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12028                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12029        int userId = UserHandle.getUserId(Binder.getCallingUid());
12030
12031        synchronized (this) {
12032
12033            // iterate across all processes
12034            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12035                ProcessRecord app = mLruProcesses.get(i);
12036                if (!allUsers && app.userId != userId) {
12037                    continue;
12038                }
12039                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12040                    // This one's in trouble, so we'll generate a report for it
12041                    // crashes are higher priority (in case there's a crash *and* an anr)
12042                    ActivityManager.ProcessErrorStateInfo report = null;
12043                    if (app.crashing) {
12044                        report = app.crashingReport;
12045                    } else if (app.notResponding) {
12046                        report = app.notRespondingReport;
12047                    }
12048
12049                    if (report != null) {
12050                        if (errList == null) {
12051                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12052                        }
12053                        errList.add(report);
12054                    } else {
12055                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12056                                " crashing = " + app.crashing +
12057                                " notResponding = " + app.notResponding);
12058                    }
12059                }
12060            }
12061        }
12062
12063        return errList;
12064    }
12065
12066    static int procStateToImportance(int procState, int memAdj,
12067            ActivityManager.RunningAppProcessInfo currApp) {
12068        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12069        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12070            currApp.lru = memAdj;
12071        } else {
12072            currApp.lru = 0;
12073        }
12074        return imp;
12075    }
12076
12077    private void fillInProcMemInfo(ProcessRecord app,
12078            ActivityManager.RunningAppProcessInfo outInfo) {
12079        outInfo.pid = app.pid;
12080        outInfo.uid = app.info.uid;
12081        if (mHeavyWeightProcess == app) {
12082            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12083        }
12084        if (app.persistent) {
12085            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12086        }
12087        if (app.activities.size() > 0) {
12088            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12089        }
12090        outInfo.lastTrimLevel = app.trimMemoryLevel;
12091        int adj = app.curAdj;
12092        int procState = app.curProcState;
12093        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12094        outInfo.importanceReasonCode = app.adjTypeCode;
12095        outInfo.processState = app.curProcState;
12096    }
12097
12098    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12099        enforceNotIsolatedCaller("getRunningAppProcesses");
12100        // Lazy instantiation of list
12101        List<ActivityManager.RunningAppProcessInfo> runList = null;
12102        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12103                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12104        int userId = UserHandle.getUserId(Binder.getCallingUid());
12105        synchronized (this) {
12106            // Iterate across all processes
12107            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12108                ProcessRecord app = mLruProcesses.get(i);
12109                if (!allUsers && app.userId != userId) {
12110                    continue;
12111                }
12112                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12113                    // Generate process state info for running application
12114                    ActivityManager.RunningAppProcessInfo currApp =
12115                        new ActivityManager.RunningAppProcessInfo(app.processName,
12116                                app.pid, app.getPackageList());
12117                    fillInProcMemInfo(app, currApp);
12118                    if (app.adjSource instanceof ProcessRecord) {
12119                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12120                        currApp.importanceReasonImportance =
12121                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12122                                        app.adjSourceProcState);
12123                    } else if (app.adjSource instanceof ActivityRecord) {
12124                        ActivityRecord r = (ActivityRecord)app.adjSource;
12125                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12126                    }
12127                    if (app.adjTarget instanceof ComponentName) {
12128                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12129                    }
12130                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12131                    //        + " lru=" + currApp.lru);
12132                    if (runList == null) {
12133                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12134                    }
12135                    runList.add(currApp);
12136                }
12137            }
12138        }
12139        return runList;
12140    }
12141
12142    public List<ApplicationInfo> getRunningExternalApplications() {
12143        enforceNotIsolatedCaller("getRunningExternalApplications");
12144        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12145        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12146        if (runningApps != null && runningApps.size() > 0) {
12147            Set<String> extList = new HashSet<String>();
12148            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12149                if (app.pkgList != null) {
12150                    for (String pkg : app.pkgList) {
12151                        extList.add(pkg);
12152                    }
12153                }
12154            }
12155            IPackageManager pm = AppGlobals.getPackageManager();
12156            for (String pkg : extList) {
12157                try {
12158                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12159                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12160                        retList.add(info);
12161                    }
12162                } catch (RemoteException e) {
12163                }
12164            }
12165        }
12166        return retList;
12167    }
12168
12169    @Override
12170    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12171        enforceNotIsolatedCaller("getMyMemoryState");
12172        synchronized (this) {
12173            ProcessRecord proc;
12174            synchronized (mPidsSelfLocked) {
12175                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12176            }
12177            fillInProcMemInfo(proc, outInfo);
12178        }
12179    }
12180
12181    @Override
12182    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12183        if (checkCallingPermission(android.Manifest.permission.DUMP)
12184                != PackageManager.PERMISSION_GRANTED) {
12185            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12186                    + Binder.getCallingPid()
12187                    + ", uid=" + Binder.getCallingUid()
12188                    + " without permission "
12189                    + android.Manifest.permission.DUMP);
12190            return;
12191        }
12192
12193        boolean dumpAll = false;
12194        boolean dumpClient = false;
12195        String dumpPackage = null;
12196
12197        int opti = 0;
12198        while (opti < args.length) {
12199            String opt = args[opti];
12200            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12201                break;
12202            }
12203            opti++;
12204            if ("-a".equals(opt)) {
12205                dumpAll = true;
12206            } else if ("-c".equals(opt)) {
12207                dumpClient = true;
12208            } else if ("-h".equals(opt)) {
12209                pw.println("Activity manager dump options:");
12210                pw.println("  [-a] [-c] [-h] [cmd] ...");
12211                pw.println("  cmd may be one of:");
12212                pw.println("    a[ctivities]: activity stack state");
12213                pw.println("    r[recents]: recent activities state");
12214                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12215                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12216                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12217                pw.println("    o[om]: out of memory management");
12218                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12219                pw.println("    provider [COMP_SPEC]: provider client-side state");
12220                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12221                pw.println("    service [COMP_SPEC]: service client-side state");
12222                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12223                pw.println("    all: dump all activities");
12224                pw.println("    top: dump the top activity");
12225                pw.println("    write: write all pending state to storage");
12226                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12227                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12228                pw.println("    a partial substring in a component name, a");
12229                pw.println("    hex object identifier.");
12230                pw.println("  -a: include all available server state.");
12231                pw.println("  -c: include client state.");
12232                return;
12233            } else {
12234                pw.println("Unknown argument: " + opt + "; use -h for help");
12235            }
12236        }
12237
12238        long origId = Binder.clearCallingIdentity();
12239        boolean more = false;
12240        // Is the caller requesting to dump a particular piece of data?
12241        if (opti < args.length) {
12242            String cmd = args[opti];
12243            opti++;
12244            if ("activities".equals(cmd) || "a".equals(cmd)) {
12245                synchronized (this) {
12246                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12247                }
12248            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12249                synchronized (this) {
12250                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12251                }
12252            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12253                String[] newArgs;
12254                String name;
12255                if (opti >= args.length) {
12256                    name = null;
12257                    newArgs = EMPTY_STRING_ARRAY;
12258                } else {
12259                    name = args[opti];
12260                    opti++;
12261                    newArgs = new String[args.length - opti];
12262                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12263                            args.length - opti);
12264                }
12265                synchronized (this) {
12266                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12267                }
12268            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12269                String[] newArgs;
12270                String name;
12271                if (opti >= args.length) {
12272                    name = null;
12273                    newArgs = EMPTY_STRING_ARRAY;
12274                } else {
12275                    name = args[opti];
12276                    opti++;
12277                    newArgs = new String[args.length - opti];
12278                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12279                            args.length - opti);
12280                }
12281                synchronized (this) {
12282                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12283                }
12284            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12285                String[] newArgs;
12286                String name;
12287                if (opti >= args.length) {
12288                    name = null;
12289                    newArgs = EMPTY_STRING_ARRAY;
12290                } else {
12291                    name = args[opti];
12292                    opti++;
12293                    newArgs = new String[args.length - opti];
12294                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12295                            args.length - opti);
12296                }
12297                synchronized (this) {
12298                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12299                }
12300            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12301                synchronized (this) {
12302                    dumpOomLocked(fd, pw, args, opti, true);
12303                }
12304            } else if ("provider".equals(cmd)) {
12305                String[] newArgs;
12306                String name;
12307                if (opti >= args.length) {
12308                    name = null;
12309                    newArgs = EMPTY_STRING_ARRAY;
12310                } else {
12311                    name = args[opti];
12312                    opti++;
12313                    newArgs = new String[args.length - opti];
12314                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12315                }
12316                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12317                    pw.println("No providers match: " + name);
12318                    pw.println("Use -h for help.");
12319                }
12320            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12321                synchronized (this) {
12322                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12323                }
12324            } else if ("service".equals(cmd)) {
12325                String[] newArgs;
12326                String name;
12327                if (opti >= args.length) {
12328                    name = null;
12329                    newArgs = EMPTY_STRING_ARRAY;
12330                } else {
12331                    name = args[opti];
12332                    opti++;
12333                    newArgs = new String[args.length - opti];
12334                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12335                            args.length - opti);
12336                }
12337                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12338                    pw.println("No services match: " + name);
12339                    pw.println("Use -h for help.");
12340                }
12341            } else if ("package".equals(cmd)) {
12342                String[] newArgs;
12343                if (opti >= args.length) {
12344                    pw.println("package: no package name specified");
12345                    pw.println("Use -h for help.");
12346                } else {
12347                    dumpPackage = args[opti];
12348                    opti++;
12349                    newArgs = new String[args.length - opti];
12350                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12351                            args.length - opti);
12352                    args = newArgs;
12353                    opti = 0;
12354                    more = true;
12355                }
12356            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12357                synchronized (this) {
12358                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12359                }
12360            } else if ("write".equals(cmd)) {
12361                mTaskPersister.flush();
12362                pw.println("All tasks persisted.");
12363                return;
12364            } else {
12365                // Dumping a single activity?
12366                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12367                    pw.println("Bad activity command, or no activities match: " + cmd);
12368                    pw.println("Use -h for help.");
12369                }
12370            }
12371            if (!more) {
12372                Binder.restoreCallingIdentity(origId);
12373                return;
12374            }
12375        }
12376
12377        // No piece of data specified, dump everything.
12378        synchronized (this) {
12379            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12380            pw.println();
12381            if (dumpAll) {
12382                pw.println("-------------------------------------------------------------------------------");
12383            }
12384            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12385            pw.println();
12386            if (dumpAll) {
12387                pw.println("-------------------------------------------------------------------------------");
12388            }
12389            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12390            pw.println();
12391            if (dumpAll) {
12392                pw.println("-------------------------------------------------------------------------------");
12393            }
12394            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12395            pw.println();
12396            if (dumpAll) {
12397                pw.println("-------------------------------------------------------------------------------");
12398            }
12399            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12400            pw.println();
12401            if (dumpAll) {
12402                pw.println("-------------------------------------------------------------------------------");
12403            }
12404            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12405            pw.println();
12406            if (dumpAll) {
12407                pw.println("-------------------------------------------------------------------------------");
12408            }
12409            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12410        }
12411        Binder.restoreCallingIdentity(origId);
12412    }
12413
12414    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12415            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12416        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12417
12418        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12419                dumpPackage);
12420        boolean needSep = printedAnything;
12421
12422        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12423                dumpPackage, needSep, "  mFocusedActivity: ");
12424        if (printed) {
12425            printedAnything = true;
12426            needSep = false;
12427        }
12428
12429        if (dumpPackage == null) {
12430            if (needSep) {
12431                pw.println();
12432            }
12433            needSep = true;
12434            printedAnything = true;
12435            mStackSupervisor.dump(pw, "  ");
12436        }
12437
12438        if (!printedAnything) {
12439            pw.println("  (nothing)");
12440        }
12441    }
12442
12443    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12444            int opti, boolean dumpAll, String dumpPackage) {
12445        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12446
12447        boolean printedAnything = false;
12448
12449        if (mRecentTasks.size() > 0) {
12450            boolean printedHeader = false;
12451
12452            final int N = mRecentTasks.size();
12453            for (int i=0; i<N; i++) {
12454                TaskRecord tr = mRecentTasks.get(i);
12455                if (dumpPackage != null) {
12456                    if (tr.realActivity == null ||
12457                            !dumpPackage.equals(tr.realActivity)) {
12458                        continue;
12459                    }
12460                }
12461                if (!printedHeader) {
12462                    pw.println("  Recent tasks:");
12463                    printedHeader = true;
12464                    printedAnything = true;
12465                }
12466                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12467                        pw.println(tr);
12468                if (dumpAll) {
12469                    mRecentTasks.get(i).dump(pw, "    ");
12470                }
12471            }
12472        }
12473
12474        if (!printedAnything) {
12475            pw.println("  (nothing)");
12476        }
12477    }
12478
12479    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12480            int opti, boolean dumpAll, String dumpPackage) {
12481        boolean needSep = false;
12482        boolean printedAnything = false;
12483        int numPers = 0;
12484
12485        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12486
12487        if (dumpAll) {
12488            final int NP = mProcessNames.getMap().size();
12489            for (int ip=0; ip<NP; ip++) {
12490                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12491                final int NA = procs.size();
12492                for (int ia=0; ia<NA; ia++) {
12493                    ProcessRecord r = procs.valueAt(ia);
12494                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12495                        continue;
12496                    }
12497                    if (!needSep) {
12498                        pw.println("  All known processes:");
12499                        needSep = true;
12500                        printedAnything = true;
12501                    }
12502                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12503                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12504                        pw.print(" "); pw.println(r);
12505                    r.dump(pw, "    ");
12506                    if (r.persistent) {
12507                        numPers++;
12508                    }
12509                }
12510            }
12511        }
12512
12513        if (mIsolatedProcesses.size() > 0) {
12514            boolean printed = false;
12515            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12516                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12517                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12518                    continue;
12519                }
12520                if (!printed) {
12521                    if (needSep) {
12522                        pw.println();
12523                    }
12524                    pw.println("  Isolated process list (sorted by uid):");
12525                    printedAnything = true;
12526                    printed = true;
12527                    needSep = true;
12528                }
12529                pw.println(String.format("%sIsolated #%2d: %s",
12530                        "    ", i, r.toString()));
12531            }
12532        }
12533
12534        if (mLruProcesses.size() > 0) {
12535            if (needSep) {
12536                pw.println();
12537            }
12538            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12539                    pw.print(" total, non-act at ");
12540                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12541                    pw.print(", non-svc at ");
12542                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12543                    pw.println("):");
12544            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12545            needSep = true;
12546            printedAnything = true;
12547        }
12548
12549        if (dumpAll || dumpPackage != null) {
12550            synchronized (mPidsSelfLocked) {
12551                boolean printed = false;
12552                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12553                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12554                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12555                        continue;
12556                    }
12557                    if (!printed) {
12558                        if (needSep) pw.println();
12559                        needSep = true;
12560                        pw.println("  PID mappings:");
12561                        printed = true;
12562                        printedAnything = true;
12563                    }
12564                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12565                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12566                }
12567            }
12568        }
12569
12570        if (mForegroundProcesses.size() > 0) {
12571            synchronized (mPidsSelfLocked) {
12572                boolean printed = false;
12573                for (int i=0; i<mForegroundProcesses.size(); i++) {
12574                    ProcessRecord r = mPidsSelfLocked.get(
12575                            mForegroundProcesses.valueAt(i).pid);
12576                    if (dumpPackage != null && (r == null
12577                            || !r.pkgList.containsKey(dumpPackage))) {
12578                        continue;
12579                    }
12580                    if (!printed) {
12581                        if (needSep) pw.println();
12582                        needSep = true;
12583                        pw.println("  Foreground Processes:");
12584                        printed = true;
12585                        printedAnything = true;
12586                    }
12587                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12588                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12589                }
12590            }
12591        }
12592
12593        if (mPersistentStartingProcesses.size() > 0) {
12594            if (needSep) pw.println();
12595            needSep = true;
12596            printedAnything = true;
12597            pw.println("  Persisent processes that are starting:");
12598            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12599                    "Starting Norm", "Restarting PERS", dumpPackage);
12600        }
12601
12602        if (mRemovedProcesses.size() > 0) {
12603            if (needSep) pw.println();
12604            needSep = true;
12605            printedAnything = true;
12606            pw.println("  Processes that are being removed:");
12607            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12608                    "Removed Norm", "Removed PERS", dumpPackage);
12609        }
12610
12611        if (mProcessesOnHold.size() > 0) {
12612            if (needSep) pw.println();
12613            needSep = true;
12614            printedAnything = true;
12615            pw.println("  Processes that are on old until the system is ready:");
12616            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12617                    "OnHold Norm", "OnHold PERS", dumpPackage);
12618        }
12619
12620        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12621
12622        if (mProcessCrashTimes.getMap().size() > 0) {
12623            boolean printed = false;
12624            long now = SystemClock.uptimeMillis();
12625            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12626            final int NP = pmap.size();
12627            for (int ip=0; ip<NP; ip++) {
12628                String pname = pmap.keyAt(ip);
12629                SparseArray<Long> uids = pmap.valueAt(ip);
12630                final int N = uids.size();
12631                for (int i=0; i<N; i++) {
12632                    int puid = uids.keyAt(i);
12633                    ProcessRecord r = mProcessNames.get(pname, puid);
12634                    if (dumpPackage != null && (r == null
12635                            || !r.pkgList.containsKey(dumpPackage))) {
12636                        continue;
12637                    }
12638                    if (!printed) {
12639                        if (needSep) pw.println();
12640                        needSep = true;
12641                        pw.println("  Time since processes crashed:");
12642                        printed = true;
12643                        printedAnything = true;
12644                    }
12645                    pw.print("    Process "); pw.print(pname);
12646                            pw.print(" uid "); pw.print(puid);
12647                            pw.print(": last crashed ");
12648                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12649                            pw.println(" ago");
12650                }
12651            }
12652        }
12653
12654        if (mBadProcesses.getMap().size() > 0) {
12655            boolean printed = false;
12656            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12657            final int NP = pmap.size();
12658            for (int ip=0; ip<NP; ip++) {
12659                String pname = pmap.keyAt(ip);
12660                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12661                final int N = uids.size();
12662                for (int i=0; i<N; i++) {
12663                    int puid = uids.keyAt(i);
12664                    ProcessRecord r = mProcessNames.get(pname, puid);
12665                    if (dumpPackage != null && (r == null
12666                            || !r.pkgList.containsKey(dumpPackage))) {
12667                        continue;
12668                    }
12669                    if (!printed) {
12670                        if (needSep) pw.println();
12671                        needSep = true;
12672                        pw.println("  Bad processes:");
12673                        printedAnything = true;
12674                    }
12675                    BadProcessInfo info = uids.valueAt(i);
12676                    pw.print("    Bad process "); pw.print(pname);
12677                            pw.print(" uid "); pw.print(puid);
12678                            pw.print(": crashed at time "); pw.println(info.time);
12679                    if (info.shortMsg != null) {
12680                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12681                    }
12682                    if (info.longMsg != null) {
12683                        pw.print("      Long msg: "); pw.println(info.longMsg);
12684                    }
12685                    if (info.stack != null) {
12686                        pw.println("      Stack:");
12687                        int lastPos = 0;
12688                        for (int pos=0; pos<info.stack.length(); pos++) {
12689                            if (info.stack.charAt(pos) == '\n') {
12690                                pw.print("        ");
12691                                pw.write(info.stack, lastPos, pos-lastPos);
12692                                pw.println();
12693                                lastPos = pos+1;
12694                            }
12695                        }
12696                        if (lastPos < info.stack.length()) {
12697                            pw.print("        ");
12698                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12699                            pw.println();
12700                        }
12701                    }
12702                }
12703            }
12704        }
12705
12706        if (dumpPackage == null) {
12707            pw.println();
12708            needSep = false;
12709            pw.println("  mStartedUsers:");
12710            for (int i=0; i<mStartedUsers.size(); i++) {
12711                UserStartedState uss = mStartedUsers.valueAt(i);
12712                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12713                        pw.print(": "); uss.dump("", pw);
12714            }
12715            pw.print("  mStartedUserArray: [");
12716            for (int i=0; i<mStartedUserArray.length; i++) {
12717                if (i > 0) pw.print(", ");
12718                pw.print(mStartedUserArray[i]);
12719            }
12720            pw.println("]");
12721            pw.print("  mUserLru: [");
12722            for (int i=0; i<mUserLru.size(); i++) {
12723                if (i > 0) pw.print(", ");
12724                pw.print(mUserLru.get(i));
12725            }
12726            pw.println("]");
12727            if (dumpAll) {
12728                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12729            }
12730            synchronized (mUserProfileGroupIdsSelfLocked) {
12731                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12732                    pw.println("  mUserProfileGroupIds:");
12733                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12734                        pw.print("    User #");
12735                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12736                        pw.print(" -> profile #");
12737                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12738                    }
12739                }
12740            }
12741        }
12742        if (mHomeProcess != null && (dumpPackage == null
12743                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12744            if (needSep) {
12745                pw.println();
12746                needSep = false;
12747            }
12748            pw.println("  mHomeProcess: " + mHomeProcess);
12749        }
12750        if (mPreviousProcess != null && (dumpPackage == null
12751                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12752            if (needSep) {
12753                pw.println();
12754                needSep = false;
12755            }
12756            pw.println("  mPreviousProcess: " + mPreviousProcess);
12757        }
12758        if (dumpAll) {
12759            StringBuilder sb = new StringBuilder(128);
12760            sb.append("  mPreviousProcessVisibleTime: ");
12761            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12762            pw.println(sb);
12763        }
12764        if (mHeavyWeightProcess != null && (dumpPackage == null
12765                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12766            if (needSep) {
12767                pw.println();
12768                needSep = false;
12769            }
12770            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12771        }
12772        if (dumpPackage == null) {
12773            pw.println("  mConfiguration: " + mConfiguration);
12774        }
12775        if (dumpAll) {
12776            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12777            if (mCompatModePackages.getPackages().size() > 0) {
12778                boolean printed = false;
12779                for (Map.Entry<String, Integer> entry
12780                        : mCompatModePackages.getPackages().entrySet()) {
12781                    String pkg = entry.getKey();
12782                    int mode = entry.getValue();
12783                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12784                        continue;
12785                    }
12786                    if (!printed) {
12787                        pw.println("  mScreenCompatPackages:");
12788                        printed = true;
12789                    }
12790                    pw.print("    "); pw.print(pkg); pw.print(": ");
12791                            pw.print(mode); pw.println();
12792                }
12793            }
12794        }
12795        if (dumpPackage == null) {
12796            if (mSleeping || mWentToSleep || mLockScreenShown) {
12797                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12798                        + " mLockScreenShown " + mLockScreenShown);
12799            }
12800            if (mShuttingDown || mRunningVoice) {
12801                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12802            }
12803        }
12804        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12805                || mOrigWaitForDebugger) {
12806            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12807                    || dumpPackage.equals(mOrigDebugApp)) {
12808                if (needSep) {
12809                    pw.println();
12810                    needSep = false;
12811                }
12812                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12813                        + " mDebugTransient=" + mDebugTransient
12814                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12815            }
12816        }
12817        if (mOpenGlTraceApp != null) {
12818            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12819                if (needSep) {
12820                    pw.println();
12821                    needSep = false;
12822                }
12823                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12824            }
12825        }
12826        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12827                || mProfileFd != null) {
12828            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12829                if (needSep) {
12830                    pw.println();
12831                    needSep = false;
12832                }
12833                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12834                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12835                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12836                        + mAutoStopProfiler);
12837                pw.println("  mProfileType=" + mProfileType);
12838            }
12839        }
12840        if (dumpPackage == null) {
12841            if (mAlwaysFinishActivities || mController != null) {
12842                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12843                        + " mController=" + mController);
12844            }
12845            if (dumpAll) {
12846                pw.println("  Total persistent processes: " + numPers);
12847                pw.println("  mProcessesReady=" + mProcessesReady
12848                        + " mSystemReady=" + mSystemReady);
12849                pw.println("  mBooting=" + mBooting
12850                        + " mBooted=" + mBooted
12851                        + " mFactoryTest=" + mFactoryTest);
12852                pw.print("  mLastPowerCheckRealtime=");
12853                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12854                        pw.println("");
12855                pw.print("  mLastPowerCheckUptime=");
12856                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12857                        pw.println("");
12858                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12859                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12860                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12861                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12862                        + " (" + mLruProcesses.size() + " total)"
12863                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12864                        + " mNumServiceProcs=" + mNumServiceProcs
12865                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12866                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12867                        + " mLastMemoryLevel" + mLastMemoryLevel
12868                        + " mLastNumProcesses" + mLastNumProcesses);
12869                long now = SystemClock.uptimeMillis();
12870                pw.print("  mLastIdleTime=");
12871                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12872                        pw.print(" mLowRamSinceLastIdle=");
12873                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12874                        pw.println();
12875            }
12876        }
12877
12878        if (!printedAnything) {
12879            pw.println("  (nothing)");
12880        }
12881    }
12882
12883    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12884            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12885        if (mProcessesToGc.size() > 0) {
12886            boolean printed = false;
12887            long now = SystemClock.uptimeMillis();
12888            for (int i=0; i<mProcessesToGc.size(); i++) {
12889                ProcessRecord proc = mProcessesToGc.get(i);
12890                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12891                    continue;
12892                }
12893                if (!printed) {
12894                    if (needSep) pw.println();
12895                    needSep = true;
12896                    pw.println("  Processes that are waiting to GC:");
12897                    printed = true;
12898                }
12899                pw.print("    Process "); pw.println(proc);
12900                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12901                        pw.print(", last gced=");
12902                        pw.print(now-proc.lastRequestedGc);
12903                        pw.print(" ms ago, last lowMem=");
12904                        pw.print(now-proc.lastLowMemory);
12905                        pw.println(" ms ago");
12906
12907            }
12908        }
12909        return needSep;
12910    }
12911
12912    void printOomLevel(PrintWriter pw, String name, int adj) {
12913        pw.print("    ");
12914        if (adj >= 0) {
12915            pw.print(' ');
12916            if (adj < 10) pw.print(' ');
12917        } else {
12918            if (adj > -10) pw.print(' ');
12919        }
12920        pw.print(adj);
12921        pw.print(": ");
12922        pw.print(name);
12923        pw.print(" (");
12924        pw.print(mProcessList.getMemLevel(adj)/1024);
12925        pw.println(" kB)");
12926    }
12927
12928    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12929            int opti, boolean dumpAll) {
12930        boolean needSep = false;
12931
12932        if (mLruProcesses.size() > 0) {
12933            if (needSep) pw.println();
12934            needSep = true;
12935            pw.println("  OOM levels:");
12936            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12937            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12938            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12939            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12940            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12941            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12942            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12943            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12944            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12945            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12946            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12947            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12948            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12949
12950            if (needSep) pw.println();
12951            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12952                    pw.print(" total, non-act at ");
12953                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12954                    pw.print(", non-svc at ");
12955                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12956                    pw.println("):");
12957            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12958            needSep = true;
12959        }
12960
12961        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12962
12963        pw.println();
12964        pw.println("  mHomeProcess: " + mHomeProcess);
12965        pw.println("  mPreviousProcess: " + mPreviousProcess);
12966        if (mHeavyWeightProcess != null) {
12967            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12968        }
12969
12970        return true;
12971    }
12972
12973    /**
12974     * There are three ways to call this:
12975     *  - no provider specified: dump all the providers
12976     *  - a flattened component name that matched an existing provider was specified as the
12977     *    first arg: dump that one provider
12978     *  - the first arg isn't the flattened component name of an existing provider:
12979     *    dump all providers whose component contains the first arg as a substring
12980     */
12981    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12982            int opti, boolean dumpAll) {
12983        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12984    }
12985
12986    static class ItemMatcher {
12987        ArrayList<ComponentName> components;
12988        ArrayList<String> strings;
12989        ArrayList<Integer> objects;
12990        boolean all;
12991
12992        ItemMatcher() {
12993            all = true;
12994        }
12995
12996        void build(String name) {
12997            ComponentName componentName = ComponentName.unflattenFromString(name);
12998            if (componentName != null) {
12999                if (components == null) {
13000                    components = new ArrayList<ComponentName>();
13001                }
13002                components.add(componentName);
13003                all = false;
13004            } else {
13005                int objectId = 0;
13006                // Not a '/' separated full component name; maybe an object ID?
13007                try {
13008                    objectId = Integer.parseInt(name, 16);
13009                    if (objects == null) {
13010                        objects = new ArrayList<Integer>();
13011                    }
13012                    objects.add(objectId);
13013                    all = false;
13014                } catch (RuntimeException e) {
13015                    // Not an integer; just do string match.
13016                    if (strings == null) {
13017                        strings = new ArrayList<String>();
13018                    }
13019                    strings.add(name);
13020                    all = false;
13021                }
13022            }
13023        }
13024
13025        int build(String[] args, int opti) {
13026            for (; opti<args.length; opti++) {
13027                String name = args[opti];
13028                if ("--".equals(name)) {
13029                    return opti+1;
13030                }
13031                build(name);
13032            }
13033            return opti;
13034        }
13035
13036        boolean match(Object object, ComponentName comp) {
13037            if (all) {
13038                return true;
13039            }
13040            if (components != null) {
13041                for (int i=0; i<components.size(); i++) {
13042                    if (components.get(i).equals(comp)) {
13043                        return true;
13044                    }
13045                }
13046            }
13047            if (objects != null) {
13048                for (int i=0; i<objects.size(); i++) {
13049                    if (System.identityHashCode(object) == objects.get(i)) {
13050                        return true;
13051                    }
13052                }
13053            }
13054            if (strings != null) {
13055                String flat = comp.flattenToString();
13056                for (int i=0; i<strings.size(); i++) {
13057                    if (flat.contains(strings.get(i))) {
13058                        return true;
13059                    }
13060                }
13061            }
13062            return false;
13063        }
13064    }
13065
13066    /**
13067     * There are three things that cmd can be:
13068     *  - a flattened component name that matches an existing activity
13069     *  - the cmd arg isn't the flattened component name of an existing activity:
13070     *    dump all activity whose component contains the cmd as a substring
13071     *  - A hex number of the ActivityRecord object instance.
13072     */
13073    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13074            int opti, boolean dumpAll) {
13075        ArrayList<ActivityRecord> activities;
13076
13077        synchronized (this) {
13078            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13079        }
13080
13081        if (activities.size() <= 0) {
13082            return false;
13083        }
13084
13085        String[] newArgs = new String[args.length - opti];
13086        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13087
13088        TaskRecord lastTask = null;
13089        boolean needSep = false;
13090        for (int i=activities.size()-1; i>=0; i--) {
13091            ActivityRecord r = activities.get(i);
13092            if (needSep) {
13093                pw.println();
13094            }
13095            needSep = true;
13096            synchronized (this) {
13097                if (lastTask != r.task) {
13098                    lastTask = r.task;
13099                    pw.print("TASK "); pw.print(lastTask.affinity);
13100                            pw.print(" id="); pw.println(lastTask.taskId);
13101                    if (dumpAll) {
13102                        lastTask.dump(pw, "  ");
13103                    }
13104                }
13105            }
13106            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13107        }
13108        return true;
13109    }
13110
13111    /**
13112     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13113     * there is a thread associated with the activity.
13114     */
13115    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13116            final ActivityRecord r, String[] args, boolean dumpAll) {
13117        String innerPrefix = prefix + "  ";
13118        synchronized (this) {
13119            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13120                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13121                    pw.print(" pid=");
13122                    if (r.app != null) pw.println(r.app.pid);
13123                    else pw.println("(not running)");
13124            if (dumpAll) {
13125                r.dump(pw, innerPrefix);
13126            }
13127        }
13128        if (r.app != null && r.app.thread != null) {
13129            // flush anything that is already in the PrintWriter since the thread is going
13130            // to write to the file descriptor directly
13131            pw.flush();
13132            try {
13133                TransferPipe tp = new TransferPipe();
13134                try {
13135                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13136                            r.appToken, innerPrefix, args);
13137                    tp.go(fd);
13138                } finally {
13139                    tp.kill();
13140                }
13141            } catch (IOException e) {
13142                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13143            } catch (RemoteException e) {
13144                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13145            }
13146        }
13147    }
13148
13149    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13150            int opti, boolean dumpAll, String dumpPackage) {
13151        boolean needSep = false;
13152        boolean onlyHistory = false;
13153        boolean printedAnything = false;
13154
13155        if ("history".equals(dumpPackage)) {
13156            if (opti < args.length && "-s".equals(args[opti])) {
13157                dumpAll = false;
13158            }
13159            onlyHistory = true;
13160            dumpPackage = null;
13161        }
13162
13163        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13164        if (!onlyHistory && dumpAll) {
13165            if (mRegisteredReceivers.size() > 0) {
13166                boolean printed = false;
13167                Iterator it = mRegisteredReceivers.values().iterator();
13168                while (it.hasNext()) {
13169                    ReceiverList r = (ReceiverList)it.next();
13170                    if (dumpPackage != null && (r.app == null ||
13171                            !dumpPackage.equals(r.app.info.packageName))) {
13172                        continue;
13173                    }
13174                    if (!printed) {
13175                        pw.println("  Registered Receivers:");
13176                        needSep = true;
13177                        printed = true;
13178                        printedAnything = true;
13179                    }
13180                    pw.print("  * "); pw.println(r);
13181                    r.dump(pw, "    ");
13182                }
13183            }
13184
13185            if (mReceiverResolver.dump(pw, needSep ?
13186                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13187                    "    ", dumpPackage, false)) {
13188                needSep = true;
13189                printedAnything = true;
13190            }
13191        }
13192
13193        for (BroadcastQueue q : mBroadcastQueues) {
13194            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13195            printedAnything |= needSep;
13196        }
13197
13198        needSep = true;
13199
13200        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13201            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13202                if (needSep) {
13203                    pw.println();
13204                }
13205                needSep = true;
13206                printedAnything = true;
13207                pw.print("  Sticky broadcasts for user ");
13208                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13209                StringBuilder sb = new StringBuilder(128);
13210                for (Map.Entry<String, ArrayList<Intent>> ent
13211                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13212                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13213                    if (dumpAll) {
13214                        pw.println(":");
13215                        ArrayList<Intent> intents = ent.getValue();
13216                        final int N = intents.size();
13217                        for (int i=0; i<N; i++) {
13218                            sb.setLength(0);
13219                            sb.append("    Intent: ");
13220                            intents.get(i).toShortString(sb, false, true, false, false);
13221                            pw.println(sb.toString());
13222                            Bundle bundle = intents.get(i).getExtras();
13223                            if (bundle != null) {
13224                                pw.print("      ");
13225                                pw.println(bundle.toString());
13226                            }
13227                        }
13228                    } else {
13229                        pw.println("");
13230                    }
13231                }
13232            }
13233        }
13234
13235        if (!onlyHistory && dumpAll) {
13236            pw.println();
13237            for (BroadcastQueue queue : mBroadcastQueues) {
13238                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13239                        + queue.mBroadcastsScheduled);
13240            }
13241            pw.println("  mHandler:");
13242            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13243            needSep = true;
13244            printedAnything = true;
13245        }
13246
13247        if (!printedAnything) {
13248            pw.println("  (nothing)");
13249        }
13250    }
13251
13252    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13253            int opti, boolean dumpAll, String dumpPackage) {
13254        boolean needSep;
13255        boolean printedAnything = false;
13256
13257        ItemMatcher matcher = new ItemMatcher();
13258        matcher.build(args, opti);
13259
13260        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13261
13262        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13263        printedAnything |= needSep;
13264
13265        if (mLaunchingProviders.size() > 0) {
13266            boolean printed = false;
13267            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13268                ContentProviderRecord r = mLaunchingProviders.get(i);
13269                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13270                    continue;
13271                }
13272                if (!printed) {
13273                    if (needSep) pw.println();
13274                    needSep = true;
13275                    pw.println("  Launching content providers:");
13276                    printed = true;
13277                    printedAnything = true;
13278                }
13279                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13280                        pw.println(r);
13281            }
13282        }
13283
13284        if (mGrantedUriPermissions.size() > 0) {
13285            boolean printed = false;
13286            int dumpUid = -2;
13287            if (dumpPackage != null) {
13288                try {
13289                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13290                } catch (NameNotFoundException e) {
13291                    dumpUid = -1;
13292                }
13293            }
13294            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13295                int uid = mGrantedUriPermissions.keyAt(i);
13296                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13297                    continue;
13298                }
13299                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13300                if (!printed) {
13301                    if (needSep) pw.println();
13302                    needSep = true;
13303                    pw.println("  Granted Uri Permissions:");
13304                    printed = true;
13305                    printedAnything = true;
13306                }
13307                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13308                for (UriPermission perm : perms.values()) {
13309                    pw.print("    "); pw.println(perm);
13310                    if (dumpAll) {
13311                        perm.dump(pw, "      ");
13312                    }
13313                }
13314            }
13315        }
13316
13317        if (!printedAnything) {
13318            pw.println("  (nothing)");
13319        }
13320    }
13321
13322    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13323            int opti, boolean dumpAll, String dumpPackage) {
13324        boolean printed = false;
13325
13326        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13327
13328        if (mIntentSenderRecords.size() > 0) {
13329            Iterator<WeakReference<PendingIntentRecord>> it
13330                    = mIntentSenderRecords.values().iterator();
13331            while (it.hasNext()) {
13332                WeakReference<PendingIntentRecord> ref = it.next();
13333                PendingIntentRecord rec = ref != null ? ref.get(): null;
13334                if (dumpPackage != null && (rec == null
13335                        || !dumpPackage.equals(rec.key.packageName))) {
13336                    continue;
13337                }
13338                printed = true;
13339                if (rec != null) {
13340                    pw.print("  * "); pw.println(rec);
13341                    if (dumpAll) {
13342                        rec.dump(pw, "    ");
13343                    }
13344                } else {
13345                    pw.print("  * "); pw.println(ref);
13346                }
13347            }
13348        }
13349
13350        if (!printed) {
13351            pw.println("  (nothing)");
13352        }
13353    }
13354
13355    private static final int dumpProcessList(PrintWriter pw,
13356            ActivityManagerService service, List list,
13357            String prefix, String normalLabel, String persistentLabel,
13358            String dumpPackage) {
13359        int numPers = 0;
13360        final int N = list.size()-1;
13361        for (int i=N; i>=0; i--) {
13362            ProcessRecord r = (ProcessRecord)list.get(i);
13363            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13364                continue;
13365            }
13366            pw.println(String.format("%s%s #%2d: %s",
13367                    prefix, (r.persistent ? persistentLabel : normalLabel),
13368                    i, r.toString()));
13369            if (r.persistent) {
13370                numPers++;
13371            }
13372        }
13373        return numPers;
13374    }
13375
13376    private static final boolean dumpProcessOomList(PrintWriter pw,
13377            ActivityManagerService service, List<ProcessRecord> origList,
13378            String prefix, String normalLabel, String persistentLabel,
13379            boolean inclDetails, String dumpPackage) {
13380
13381        ArrayList<Pair<ProcessRecord, Integer>> list
13382                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13383        for (int i=0; i<origList.size(); i++) {
13384            ProcessRecord r = origList.get(i);
13385            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13386                continue;
13387            }
13388            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13389        }
13390
13391        if (list.size() <= 0) {
13392            return false;
13393        }
13394
13395        Comparator<Pair<ProcessRecord, Integer>> comparator
13396                = new Comparator<Pair<ProcessRecord, Integer>>() {
13397            @Override
13398            public int compare(Pair<ProcessRecord, Integer> object1,
13399                    Pair<ProcessRecord, Integer> object2) {
13400                if (object1.first.setAdj != object2.first.setAdj) {
13401                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13402                }
13403                if (object1.second.intValue() != object2.second.intValue()) {
13404                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13405                }
13406                return 0;
13407            }
13408        };
13409
13410        Collections.sort(list, comparator);
13411
13412        final long curRealtime = SystemClock.elapsedRealtime();
13413        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13414        final long curUptime = SystemClock.uptimeMillis();
13415        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13416
13417        for (int i=list.size()-1; i>=0; i--) {
13418            ProcessRecord r = list.get(i).first;
13419            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13420            char schedGroup;
13421            switch (r.setSchedGroup) {
13422                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13423                    schedGroup = 'B';
13424                    break;
13425                case Process.THREAD_GROUP_DEFAULT:
13426                    schedGroup = 'F';
13427                    break;
13428                default:
13429                    schedGroup = '?';
13430                    break;
13431            }
13432            char foreground;
13433            if (r.foregroundActivities) {
13434                foreground = 'A';
13435            } else if (r.foregroundServices) {
13436                foreground = 'S';
13437            } else {
13438                foreground = ' ';
13439            }
13440            String procState = ProcessList.makeProcStateString(r.curProcState);
13441            pw.print(prefix);
13442            pw.print(r.persistent ? persistentLabel : normalLabel);
13443            pw.print(" #");
13444            int num = (origList.size()-1)-list.get(i).second;
13445            if (num < 10) pw.print(' ');
13446            pw.print(num);
13447            pw.print(": ");
13448            pw.print(oomAdj);
13449            pw.print(' ');
13450            pw.print(schedGroup);
13451            pw.print('/');
13452            pw.print(foreground);
13453            pw.print('/');
13454            pw.print(procState);
13455            pw.print(" trm:");
13456            if (r.trimMemoryLevel < 10) pw.print(' ');
13457            pw.print(r.trimMemoryLevel);
13458            pw.print(' ');
13459            pw.print(r.toShortString());
13460            pw.print(" (");
13461            pw.print(r.adjType);
13462            pw.println(')');
13463            if (r.adjSource != null || r.adjTarget != null) {
13464                pw.print(prefix);
13465                pw.print("    ");
13466                if (r.adjTarget instanceof ComponentName) {
13467                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13468                } else if (r.adjTarget != null) {
13469                    pw.print(r.adjTarget.toString());
13470                } else {
13471                    pw.print("{null}");
13472                }
13473                pw.print("<=");
13474                if (r.adjSource instanceof ProcessRecord) {
13475                    pw.print("Proc{");
13476                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13477                    pw.println("}");
13478                } else if (r.adjSource != null) {
13479                    pw.println(r.adjSource.toString());
13480                } else {
13481                    pw.println("{null}");
13482                }
13483            }
13484            if (inclDetails) {
13485                pw.print(prefix);
13486                pw.print("    ");
13487                pw.print("oom: max="); pw.print(r.maxAdj);
13488                pw.print(" curRaw="); pw.print(r.curRawAdj);
13489                pw.print(" setRaw="); pw.print(r.setRawAdj);
13490                pw.print(" cur="); pw.print(r.curAdj);
13491                pw.print(" set="); pw.println(r.setAdj);
13492                pw.print(prefix);
13493                pw.print("    ");
13494                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13495                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13496                pw.print(" lastPss="); pw.print(r.lastPss);
13497                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13498                pw.print(prefix);
13499                pw.print("    ");
13500                pw.print("cached="); pw.print(r.cached);
13501                pw.print(" empty="); pw.print(r.empty);
13502                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13503
13504                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13505                    if (r.lastWakeTime != 0) {
13506                        long wtime;
13507                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13508                        synchronized (stats) {
13509                            wtime = stats.getProcessWakeTime(r.info.uid,
13510                                    r.pid, curRealtime);
13511                        }
13512                        long timeUsed = wtime - r.lastWakeTime;
13513                        pw.print(prefix);
13514                        pw.print("    ");
13515                        pw.print("keep awake over ");
13516                        TimeUtils.formatDuration(realtimeSince, pw);
13517                        pw.print(" used ");
13518                        TimeUtils.formatDuration(timeUsed, pw);
13519                        pw.print(" (");
13520                        pw.print((timeUsed*100)/realtimeSince);
13521                        pw.println("%)");
13522                    }
13523                    if (r.lastCpuTime != 0) {
13524                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13525                        pw.print(prefix);
13526                        pw.print("    ");
13527                        pw.print("run cpu over ");
13528                        TimeUtils.formatDuration(uptimeSince, pw);
13529                        pw.print(" used ");
13530                        TimeUtils.formatDuration(timeUsed, pw);
13531                        pw.print(" (");
13532                        pw.print((timeUsed*100)/uptimeSince);
13533                        pw.println("%)");
13534                    }
13535                }
13536            }
13537        }
13538        return true;
13539    }
13540
13541    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13542        ArrayList<ProcessRecord> procs;
13543        synchronized (this) {
13544            if (args != null && args.length > start
13545                    && args[start].charAt(0) != '-') {
13546                procs = new ArrayList<ProcessRecord>();
13547                int pid = -1;
13548                try {
13549                    pid = Integer.parseInt(args[start]);
13550                } catch (NumberFormatException e) {
13551                }
13552                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13553                    ProcessRecord proc = mLruProcesses.get(i);
13554                    if (proc.pid == pid) {
13555                        procs.add(proc);
13556                    } else if (proc.processName.equals(args[start])) {
13557                        procs.add(proc);
13558                    }
13559                }
13560                if (procs.size() <= 0) {
13561                    return null;
13562                }
13563            } else {
13564                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13565            }
13566        }
13567        return procs;
13568    }
13569
13570    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13571            PrintWriter pw, String[] args) {
13572        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13573        if (procs == null) {
13574            pw.println("No process found for: " + args[0]);
13575            return;
13576        }
13577
13578        long uptime = SystemClock.uptimeMillis();
13579        long realtime = SystemClock.elapsedRealtime();
13580        pw.println("Applications Graphics Acceleration Info:");
13581        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13582
13583        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13584            ProcessRecord r = procs.get(i);
13585            if (r.thread != null) {
13586                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13587                pw.flush();
13588                try {
13589                    TransferPipe tp = new TransferPipe();
13590                    try {
13591                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13592                        tp.go(fd);
13593                    } finally {
13594                        tp.kill();
13595                    }
13596                } catch (IOException e) {
13597                    pw.println("Failure while dumping the app: " + r);
13598                    pw.flush();
13599                } catch (RemoteException e) {
13600                    pw.println("Got a RemoteException while dumping the app " + r);
13601                    pw.flush();
13602                }
13603            }
13604        }
13605    }
13606
13607    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13608        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13609        if (procs == null) {
13610            pw.println("No process found for: " + args[0]);
13611            return;
13612        }
13613
13614        pw.println("Applications Database Info:");
13615
13616        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13617            ProcessRecord r = procs.get(i);
13618            if (r.thread != null) {
13619                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13620                pw.flush();
13621                try {
13622                    TransferPipe tp = new TransferPipe();
13623                    try {
13624                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13625                        tp.go(fd);
13626                    } finally {
13627                        tp.kill();
13628                    }
13629                } catch (IOException e) {
13630                    pw.println("Failure while dumping the app: " + r);
13631                    pw.flush();
13632                } catch (RemoteException e) {
13633                    pw.println("Got a RemoteException while dumping the app " + r);
13634                    pw.flush();
13635                }
13636            }
13637        }
13638    }
13639
13640    final static class MemItem {
13641        final boolean isProc;
13642        final String label;
13643        final String shortLabel;
13644        final long pss;
13645        final int id;
13646        final boolean hasActivities;
13647        ArrayList<MemItem> subitems;
13648
13649        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13650                boolean _hasActivities) {
13651            isProc = true;
13652            label = _label;
13653            shortLabel = _shortLabel;
13654            pss = _pss;
13655            id = _id;
13656            hasActivities = _hasActivities;
13657        }
13658
13659        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13660            isProc = false;
13661            label = _label;
13662            shortLabel = _shortLabel;
13663            pss = _pss;
13664            id = _id;
13665            hasActivities = false;
13666        }
13667    }
13668
13669    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13670            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13671        if (sort && !isCompact) {
13672            Collections.sort(items, new Comparator<MemItem>() {
13673                @Override
13674                public int compare(MemItem lhs, MemItem rhs) {
13675                    if (lhs.pss < rhs.pss) {
13676                        return 1;
13677                    } else if (lhs.pss > rhs.pss) {
13678                        return -1;
13679                    }
13680                    return 0;
13681                }
13682            });
13683        }
13684
13685        for (int i=0; i<items.size(); i++) {
13686            MemItem mi = items.get(i);
13687            if (!isCompact) {
13688                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13689            } else if (mi.isProc) {
13690                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13691                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13692                pw.println(mi.hasActivities ? ",a" : ",e");
13693            } else {
13694                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13695                pw.println(mi.pss);
13696            }
13697            if (mi.subitems != null) {
13698                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13699                        true, isCompact);
13700            }
13701        }
13702    }
13703
13704    // These are in KB.
13705    static final long[] DUMP_MEM_BUCKETS = new long[] {
13706        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13707        120*1024, 160*1024, 200*1024,
13708        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13709        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13710    };
13711
13712    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13713            boolean stackLike) {
13714        int start = label.lastIndexOf('.');
13715        if (start >= 0) start++;
13716        else start = 0;
13717        int end = label.length();
13718        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13719            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13720                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13721                out.append(bucket);
13722                out.append(stackLike ? "MB." : "MB ");
13723                out.append(label, start, end);
13724                return;
13725            }
13726        }
13727        out.append(memKB/1024);
13728        out.append(stackLike ? "MB." : "MB ");
13729        out.append(label, start, end);
13730    }
13731
13732    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13733            ProcessList.NATIVE_ADJ,
13734            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13735            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13736            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13737            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13738            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13739    };
13740    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13741            "Native",
13742            "System", "Persistent", "Foreground",
13743            "Visible", "Perceptible",
13744            "Heavy Weight", "Backup",
13745            "A Services", "Home",
13746            "Previous", "B Services", "Cached"
13747    };
13748    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13749            "native",
13750            "sys", "pers", "fore",
13751            "vis", "percept",
13752            "heavy", "backup",
13753            "servicea", "home",
13754            "prev", "serviceb", "cached"
13755    };
13756
13757    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13758            long realtime, boolean isCheckinRequest, boolean isCompact) {
13759        if (isCheckinRequest || isCompact) {
13760            // short checkin version
13761            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13762        } else {
13763            pw.println("Applications Memory Usage (kB):");
13764            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13765        }
13766    }
13767
13768    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13769            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13770        boolean dumpDetails = false;
13771        boolean dumpFullDetails = false;
13772        boolean dumpDalvik = false;
13773        boolean oomOnly = false;
13774        boolean isCompact = false;
13775        boolean localOnly = false;
13776
13777        int opti = 0;
13778        while (opti < args.length) {
13779            String opt = args[opti];
13780            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13781                break;
13782            }
13783            opti++;
13784            if ("-a".equals(opt)) {
13785                dumpDetails = true;
13786                dumpFullDetails = true;
13787                dumpDalvik = true;
13788            } else if ("-d".equals(opt)) {
13789                dumpDalvik = true;
13790            } else if ("-c".equals(opt)) {
13791                isCompact = true;
13792            } else if ("--oom".equals(opt)) {
13793                oomOnly = true;
13794            } else if ("--local".equals(opt)) {
13795                localOnly = true;
13796            } else if ("-h".equals(opt)) {
13797                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13798                pw.println("  -a: include all available information for each process.");
13799                pw.println("  -d: include dalvik details when dumping process details.");
13800                pw.println("  -c: dump in a compact machine-parseable representation.");
13801                pw.println("  --oom: only show processes organized by oom adj.");
13802                pw.println("  --local: only collect details locally, don't call process.");
13803                pw.println("If [process] is specified it can be the name or ");
13804                pw.println("pid of a specific process to dump.");
13805                return;
13806            } else {
13807                pw.println("Unknown argument: " + opt + "; use -h for help");
13808            }
13809        }
13810
13811        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13812        long uptime = SystemClock.uptimeMillis();
13813        long realtime = SystemClock.elapsedRealtime();
13814        final long[] tmpLong = new long[1];
13815
13816        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13817        if (procs == null) {
13818            // No Java processes.  Maybe they want to print a native process.
13819            if (args != null && args.length > opti
13820                    && args[opti].charAt(0) != '-') {
13821                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13822                        = new ArrayList<ProcessCpuTracker.Stats>();
13823                updateCpuStatsNow();
13824                int findPid = -1;
13825                try {
13826                    findPid = Integer.parseInt(args[opti]);
13827                } catch (NumberFormatException e) {
13828                }
13829                synchronized (mProcessCpuTracker) {
13830                    final int N = mProcessCpuTracker.countStats();
13831                    for (int i=0; i<N; i++) {
13832                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13833                        if (st.pid == findPid || (st.baseName != null
13834                                && st.baseName.equals(args[opti]))) {
13835                            nativeProcs.add(st);
13836                        }
13837                    }
13838                }
13839                if (nativeProcs.size() > 0) {
13840                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13841                            isCompact);
13842                    Debug.MemoryInfo mi = null;
13843                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13844                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13845                        final int pid = r.pid;
13846                        if (!isCheckinRequest && dumpDetails) {
13847                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13848                        }
13849                        if (mi == null) {
13850                            mi = new Debug.MemoryInfo();
13851                        }
13852                        if (dumpDetails || (!brief && !oomOnly)) {
13853                            Debug.getMemoryInfo(pid, mi);
13854                        } else {
13855                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13856                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13857                        }
13858                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13859                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13860                        if (isCheckinRequest) {
13861                            pw.println();
13862                        }
13863                    }
13864                    return;
13865                }
13866            }
13867            pw.println("No process found for: " + args[opti]);
13868            return;
13869        }
13870
13871        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13872            dumpDetails = true;
13873        }
13874
13875        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13876
13877        String[] innerArgs = new String[args.length-opti];
13878        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13879
13880        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13881        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13882        long nativePss=0, dalvikPss=0, otherPss=0;
13883        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13884
13885        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13886        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13887                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13888
13889        long totalPss = 0;
13890        long cachedPss = 0;
13891
13892        Debug.MemoryInfo mi = null;
13893        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13894            final ProcessRecord r = procs.get(i);
13895            final IApplicationThread thread;
13896            final int pid;
13897            final int oomAdj;
13898            final boolean hasActivities;
13899            synchronized (this) {
13900                thread = r.thread;
13901                pid = r.pid;
13902                oomAdj = r.getSetAdjWithServices();
13903                hasActivities = r.activities.size() > 0;
13904            }
13905            if (thread != null) {
13906                if (!isCheckinRequest && dumpDetails) {
13907                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13908                }
13909                if (mi == null) {
13910                    mi = new Debug.MemoryInfo();
13911                }
13912                if (dumpDetails || (!brief && !oomOnly)) {
13913                    Debug.getMemoryInfo(pid, mi);
13914                } else {
13915                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13916                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13917                }
13918                if (dumpDetails) {
13919                    if (localOnly) {
13920                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13921                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13922                        if (isCheckinRequest) {
13923                            pw.println();
13924                        }
13925                    } else {
13926                        try {
13927                            pw.flush();
13928                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13929                                    dumpDalvik, innerArgs);
13930                        } catch (RemoteException e) {
13931                            if (!isCheckinRequest) {
13932                                pw.println("Got RemoteException!");
13933                                pw.flush();
13934                            }
13935                        }
13936                    }
13937                }
13938
13939                final long myTotalPss = mi.getTotalPss();
13940                final long myTotalUss = mi.getTotalUss();
13941
13942                synchronized (this) {
13943                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13944                        // Record this for posterity if the process has been stable.
13945                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13946                    }
13947                }
13948
13949                if (!isCheckinRequest && mi != null) {
13950                    totalPss += myTotalPss;
13951                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13952                            (hasActivities ? " / activities)" : ")"),
13953                            r.processName, myTotalPss, pid, hasActivities);
13954                    procMems.add(pssItem);
13955                    procMemsMap.put(pid, pssItem);
13956
13957                    nativePss += mi.nativePss;
13958                    dalvikPss += mi.dalvikPss;
13959                    otherPss += mi.otherPss;
13960                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13961                        long mem = mi.getOtherPss(j);
13962                        miscPss[j] += mem;
13963                        otherPss -= mem;
13964                    }
13965
13966                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13967                        cachedPss += myTotalPss;
13968                    }
13969
13970                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13971                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13972                                || oomIndex == (oomPss.length-1)) {
13973                            oomPss[oomIndex] += myTotalPss;
13974                            if (oomProcs[oomIndex] == null) {
13975                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13976                            }
13977                            oomProcs[oomIndex].add(pssItem);
13978                            break;
13979                        }
13980                    }
13981                }
13982            }
13983        }
13984
13985        long nativeProcTotalPss = 0;
13986
13987        if (!isCheckinRequest && procs.size() > 1) {
13988            // If we are showing aggregations, also look for native processes to
13989            // include so that our aggregations are more accurate.
13990            updateCpuStatsNow();
13991            synchronized (mProcessCpuTracker) {
13992                final int N = mProcessCpuTracker.countStats();
13993                for (int i=0; i<N; i++) {
13994                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13995                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13996                        if (mi == null) {
13997                            mi = new Debug.MemoryInfo();
13998                        }
13999                        if (!brief && !oomOnly) {
14000                            Debug.getMemoryInfo(st.pid, mi);
14001                        } else {
14002                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14003                            mi.nativePrivateDirty = (int)tmpLong[0];
14004                        }
14005
14006                        final long myTotalPss = mi.getTotalPss();
14007                        totalPss += myTotalPss;
14008                        nativeProcTotalPss += myTotalPss;
14009
14010                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14011                                st.name, myTotalPss, st.pid, false);
14012                        procMems.add(pssItem);
14013
14014                        nativePss += mi.nativePss;
14015                        dalvikPss += mi.dalvikPss;
14016                        otherPss += mi.otherPss;
14017                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14018                            long mem = mi.getOtherPss(j);
14019                            miscPss[j] += mem;
14020                            otherPss -= mem;
14021                        }
14022                        oomPss[0] += myTotalPss;
14023                        if (oomProcs[0] == null) {
14024                            oomProcs[0] = new ArrayList<MemItem>();
14025                        }
14026                        oomProcs[0].add(pssItem);
14027                    }
14028                }
14029            }
14030
14031            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14032
14033            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14034            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14035            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14036            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14037                String label = Debug.MemoryInfo.getOtherLabel(j);
14038                catMems.add(new MemItem(label, label, miscPss[j], j));
14039            }
14040
14041            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14042            for (int j=0; j<oomPss.length; j++) {
14043                if (oomPss[j] != 0) {
14044                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14045                            : DUMP_MEM_OOM_LABEL[j];
14046                    MemItem item = new MemItem(label, label, oomPss[j],
14047                            DUMP_MEM_OOM_ADJ[j]);
14048                    item.subitems = oomProcs[j];
14049                    oomMems.add(item);
14050                }
14051            }
14052
14053            if (!brief && !oomOnly && !isCompact) {
14054                pw.println();
14055                pw.println("Total PSS by process:");
14056                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14057                pw.println();
14058            }
14059            if (!isCompact) {
14060                pw.println("Total PSS by OOM adjustment:");
14061            }
14062            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14063            if (!brief && !oomOnly) {
14064                PrintWriter out = categoryPw != null ? categoryPw : pw;
14065                if (!isCompact) {
14066                    out.println();
14067                    out.println("Total PSS by category:");
14068                }
14069                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14070            }
14071            if (!isCompact) {
14072                pw.println();
14073            }
14074            MemInfoReader memInfo = new MemInfoReader();
14075            memInfo.readMemInfo();
14076            if (nativeProcTotalPss > 0) {
14077                synchronized (this) {
14078                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14079                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14080                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14081                            nativeProcTotalPss);
14082                }
14083            }
14084            if (!brief) {
14085                if (!isCompact) {
14086                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14087                    pw.print(" kB (status ");
14088                    switch (mLastMemoryLevel) {
14089                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14090                            pw.println("normal)");
14091                            break;
14092                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14093                            pw.println("moderate)");
14094                            break;
14095                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14096                            pw.println("low)");
14097                            break;
14098                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14099                            pw.println("critical)");
14100                            break;
14101                        default:
14102                            pw.print(mLastMemoryLevel);
14103                            pw.println(")");
14104                            break;
14105                    }
14106                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14107                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14108                            pw.print(cachedPss); pw.print(" cached pss + ");
14109                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14110                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14111                } else {
14112                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14113                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14114                            + memInfo.getFreeSizeKb()); pw.print(",");
14115                    pw.println(totalPss - cachedPss);
14116                }
14117            }
14118            if (!isCompact) {
14119                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14120                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14121                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14122                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14123                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14124                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14125                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14126                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14127                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14128                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14129                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14130            }
14131            if (!brief) {
14132                if (memInfo.getZramTotalSizeKb() != 0) {
14133                    if (!isCompact) {
14134                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14135                                pw.print(" kB physical used for ");
14136                                pw.print(memInfo.getSwapTotalSizeKb()
14137                                        - memInfo.getSwapFreeSizeKb());
14138                                pw.print(" kB in swap (");
14139                                pw.print(memInfo.getSwapTotalSizeKb());
14140                                pw.println(" kB total swap)");
14141                    } else {
14142                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14143                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14144                                pw.println(memInfo.getSwapFreeSizeKb());
14145                    }
14146                }
14147                final int[] SINGLE_LONG_FORMAT = new int[] {
14148                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14149                };
14150                long[] longOut = new long[1];
14151                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14152                        SINGLE_LONG_FORMAT, null, longOut, null);
14153                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14154                longOut[0] = 0;
14155                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14156                        SINGLE_LONG_FORMAT, null, longOut, null);
14157                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14158                longOut[0] = 0;
14159                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14160                        SINGLE_LONG_FORMAT, null, longOut, null);
14161                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14162                longOut[0] = 0;
14163                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14164                        SINGLE_LONG_FORMAT, null, longOut, null);
14165                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14166                if (!isCompact) {
14167                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14168                        pw.print("      KSM: "); pw.print(sharing);
14169                                pw.print(" kB saved from shared ");
14170                                pw.print(shared); pw.println(" kB");
14171                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14172                                pw.print(voltile); pw.println(" kB volatile");
14173                    }
14174                    pw.print("   Tuning: ");
14175                    pw.print(ActivityManager.staticGetMemoryClass());
14176                    pw.print(" (large ");
14177                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14178                    pw.print("), oom ");
14179                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14180                    pw.print(" kB");
14181                    pw.print(", restore limit ");
14182                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14183                    pw.print(" kB");
14184                    if (ActivityManager.isLowRamDeviceStatic()) {
14185                        pw.print(" (low-ram)");
14186                    }
14187                    if (ActivityManager.isHighEndGfx()) {
14188                        pw.print(" (high-end-gfx)");
14189                    }
14190                    pw.println();
14191                } else {
14192                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14193                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14194                    pw.println(voltile);
14195                    pw.print("tuning,");
14196                    pw.print(ActivityManager.staticGetMemoryClass());
14197                    pw.print(',');
14198                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14199                    pw.print(',');
14200                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14201                    if (ActivityManager.isLowRamDeviceStatic()) {
14202                        pw.print(",low-ram");
14203                    }
14204                    if (ActivityManager.isHighEndGfx()) {
14205                        pw.print(",high-end-gfx");
14206                    }
14207                    pw.println();
14208                }
14209            }
14210        }
14211    }
14212
14213    /**
14214     * Searches array of arguments for the specified string
14215     * @param args array of argument strings
14216     * @param value value to search for
14217     * @return true if the value is contained in the array
14218     */
14219    private static boolean scanArgs(String[] args, String value) {
14220        if (args != null) {
14221            for (String arg : args) {
14222                if (value.equals(arg)) {
14223                    return true;
14224                }
14225            }
14226        }
14227        return false;
14228    }
14229
14230    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14231            ContentProviderRecord cpr, boolean always) {
14232        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14233
14234        if (!inLaunching || always) {
14235            synchronized (cpr) {
14236                cpr.launchingApp = null;
14237                cpr.notifyAll();
14238            }
14239            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14240            String names[] = cpr.info.authority.split(";");
14241            for (int j = 0; j < names.length; j++) {
14242                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14243            }
14244        }
14245
14246        for (int i=0; i<cpr.connections.size(); i++) {
14247            ContentProviderConnection conn = cpr.connections.get(i);
14248            if (conn.waiting) {
14249                // If this connection is waiting for the provider, then we don't
14250                // need to mess with its process unless we are always removing
14251                // or for some reason the provider is not currently launching.
14252                if (inLaunching && !always) {
14253                    continue;
14254                }
14255            }
14256            ProcessRecord capp = conn.client;
14257            conn.dead = true;
14258            if (conn.stableCount > 0) {
14259                if (!capp.persistent && capp.thread != null
14260                        && capp.pid != 0
14261                        && capp.pid != MY_PID) {
14262                    capp.kill("depends on provider "
14263                            + cpr.name.flattenToShortString()
14264                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14265                }
14266            } else if (capp.thread != null && conn.provider.provider != null) {
14267                try {
14268                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14269                } catch (RemoteException e) {
14270                }
14271                // In the protocol here, we don't expect the client to correctly
14272                // clean up this connection, we'll just remove it.
14273                cpr.connections.remove(i);
14274                conn.client.conProviders.remove(conn);
14275            }
14276        }
14277
14278        if (inLaunching && always) {
14279            mLaunchingProviders.remove(cpr);
14280        }
14281        return inLaunching;
14282    }
14283
14284    /**
14285     * Main code for cleaning up a process when it has gone away.  This is
14286     * called both as a result of the process dying, or directly when stopping
14287     * a process when running in single process mode.
14288     */
14289    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14290            boolean restarting, boolean allowRestart, int index) {
14291        if (index >= 0) {
14292            removeLruProcessLocked(app);
14293            ProcessList.remove(app.pid);
14294        }
14295
14296        mProcessesToGc.remove(app);
14297        mPendingPssProcesses.remove(app);
14298
14299        // Dismiss any open dialogs.
14300        if (app.crashDialog != null && !app.forceCrashReport) {
14301            app.crashDialog.dismiss();
14302            app.crashDialog = null;
14303        }
14304        if (app.anrDialog != null) {
14305            app.anrDialog.dismiss();
14306            app.anrDialog = null;
14307        }
14308        if (app.waitDialog != null) {
14309            app.waitDialog.dismiss();
14310            app.waitDialog = null;
14311        }
14312
14313        app.crashing = false;
14314        app.notResponding = false;
14315
14316        app.resetPackageList(mProcessStats);
14317        app.unlinkDeathRecipient();
14318        app.makeInactive(mProcessStats);
14319        app.waitingToKill = null;
14320        app.forcingToForeground = null;
14321        updateProcessForegroundLocked(app, false, false);
14322        app.foregroundActivities = false;
14323        app.hasShownUi = false;
14324        app.treatLikeActivity = false;
14325        app.hasAboveClient = false;
14326        app.hasClientActivities = false;
14327
14328        mServices.killServicesLocked(app, allowRestart);
14329
14330        boolean restart = false;
14331
14332        // Remove published content providers.
14333        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14334            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14335            final boolean always = app.bad || !allowRestart;
14336            if (removeDyingProviderLocked(app, cpr, always) || always) {
14337                // We left the provider in the launching list, need to
14338                // restart it.
14339                restart = true;
14340            }
14341
14342            cpr.provider = null;
14343            cpr.proc = null;
14344        }
14345        app.pubProviders.clear();
14346
14347        // Take care of any launching providers waiting for this process.
14348        if (checkAppInLaunchingProvidersLocked(app, false)) {
14349            restart = true;
14350        }
14351
14352        // Unregister from connected content providers.
14353        if (!app.conProviders.isEmpty()) {
14354            for (int i=0; i<app.conProviders.size(); i++) {
14355                ContentProviderConnection conn = app.conProviders.get(i);
14356                conn.provider.connections.remove(conn);
14357            }
14358            app.conProviders.clear();
14359        }
14360
14361        // At this point there may be remaining entries in mLaunchingProviders
14362        // where we were the only one waiting, so they are no longer of use.
14363        // Look for these and clean up if found.
14364        // XXX Commented out for now.  Trying to figure out a way to reproduce
14365        // the actual situation to identify what is actually going on.
14366        if (false) {
14367            for (int i=0; i<mLaunchingProviders.size(); i++) {
14368                ContentProviderRecord cpr = (ContentProviderRecord)
14369                        mLaunchingProviders.get(i);
14370                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14371                    synchronized (cpr) {
14372                        cpr.launchingApp = null;
14373                        cpr.notifyAll();
14374                    }
14375                }
14376            }
14377        }
14378
14379        skipCurrentReceiverLocked(app);
14380
14381        // Unregister any receivers.
14382        for (int i=app.receivers.size()-1; i>=0; i--) {
14383            removeReceiverLocked(app.receivers.valueAt(i));
14384        }
14385        app.receivers.clear();
14386
14387        // If the app is undergoing backup, tell the backup manager about it
14388        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14389            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14390                    + mBackupTarget.appInfo + " died during backup");
14391            try {
14392                IBackupManager bm = IBackupManager.Stub.asInterface(
14393                        ServiceManager.getService(Context.BACKUP_SERVICE));
14394                bm.agentDisconnected(app.info.packageName);
14395            } catch (RemoteException e) {
14396                // can't happen; backup manager is local
14397            }
14398        }
14399
14400        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14401            ProcessChangeItem item = mPendingProcessChanges.get(i);
14402            if (item.pid == app.pid) {
14403                mPendingProcessChanges.remove(i);
14404                mAvailProcessChanges.add(item);
14405            }
14406        }
14407        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14408
14409        // If the caller is restarting this app, then leave it in its
14410        // current lists and let the caller take care of it.
14411        if (restarting) {
14412            return;
14413        }
14414
14415        if (!app.persistent || app.isolated) {
14416            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14417                    "Removing non-persistent process during cleanup: " + app);
14418            mProcessNames.remove(app.processName, app.uid);
14419            mIsolatedProcesses.remove(app.uid);
14420            if (mHeavyWeightProcess == app) {
14421                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14422                        mHeavyWeightProcess.userId, 0));
14423                mHeavyWeightProcess = null;
14424            }
14425        } else if (!app.removed) {
14426            // This app is persistent, so we need to keep its record around.
14427            // If it is not already on the pending app list, add it there
14428            // and start a new process for it.
14429            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14430                mPersistentStartingProcesses.add(app);
14431                restart = true;
14432            }
14433        }
14434        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14435                "Clean-up removing on hold: " + app);
14436        mProcessesOnHold.remove(app);
14437
14438        if (app == mHomeProcess) {
14439            mHomeProcess = null;
14440        }
14441        if (app == mPreviousProcess) {
14442            mPreviousProcess = null;
14443        }
14444
14445        if (restart && !app.isolated) {
14446            // We have components that still need to be running in the
14447            // process, so re-launch it.
14448            mProcessNames.put(app.processName, app.uid, app);
14449            startProcessLocked(app, "restart", app.processName);
14450        } else if (app.pid > 0 && app.pid != MY_PID) {
14451            // Goodbye!
14452            boolean removed;
14453            synchronized (mPidsSelfLocked) {
14454                mPidsSelfLocked.remove(app.pid);
14455                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14456            }
14457            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14458            if (app.isolated) {
14459                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14460            }
14461            app.setPid(0);
14462        }
14463    }
14464
14465    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14466        // Look through the content providers we are waiting to have launched,
14467        // and if any run in this process then either schedule a restart of
14468        // the process or kill the client waiting for it if this process has
14469        // gone bad.
14470        int NL = mLaunchingProviders.size();
14471        boolean restart = false;
14472        for (int i=0; i<NL; i++) {
14473            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14474            if (cpr.launchingApp == app) {
14475                if (!alwaysBad && !app.bad) {
14476                    restart = true;
14477                } else {
14478                    removeDyingProviderLocked(app, cpr, true);
14479                    // cpr should have been removed from mLaunchingProviders
14480                    NL = mLaunchingProviders.size();
14481                    i--;
14482                }
14483            }
14484        }
14485        return restart;
14486    }
14487
14488    // =========================================================
14489    // SERVICES
14490    // =========================================================
14491
14492    @Override
14493    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14494            int flags) {
14495        enforceNotIsolatedCaller("getServices");
14496        synchronized (this) {
14497            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14498        }
14499    }
14500
14501    @Override
14502    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14503        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14504        synchronized (this) {
14505            return mServices.getRunningServiceControlPanelLocked(name);
14506        }
14507    }
14508
14509    @Override
14510    public ComponentName startService(IApplicationThread caller, Intent service,
14511            String resolvedType, int userId) {
14512        enforceNotIsolatedCaller("startService");
14513        // Refuse possible leaked file descriptors
14514        if (service != null && service.hasFileDescriptors() == true) {
14515            throw new IllegalArgumentException("File descriptors passed in Intent");
14516        }
14517
14518        if (DEBUG_SERVICE)
14519            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14520        synchronized(this) {
14521            final int callingPid = Binder.getCallingPid();
14522            final int callingUid = Binder.getCallingUid();
14523            final long origId = Binder.clearCallingIdentity();
14524            ComponentName res = mServices.startServiceLocked(caller, service,
14525                    resolvedType, callingPid, callingUid, userId);
14526            Binder.restoreCallingIdentity(origId);
14527            return res;
14528        }
14529    }
14530
14531    ComponentName startServiceInPackage(int uid,
14532            Intent service, String resolvedType, int userId) {
14533        synchronized(this) {
14534            if (DEBUG_SERVICE)
14535                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14536            final long origId = Binder.clearCallingIdentity();
14537            ComponentName res = mServices.startServiceLocked(null, service,
14538                    resolvedType, -1, uid, userId);
14539            Binder.restoreCallingIdentity(origId);
14540            return res;
14541        }
14542    }
14543
14544    @Override
14545    public int stopService(IApplicationThread caller, Intent service,
14546            String resolvedType, int userId) {
14547        enforceNotIsolatedCaller("stopService");
14548        // Refuse possible leaked file descriptors
14549        if (service != null && service.hasFileDescriptors() == true) {
14550            throw new IllegalArgumentException("File descriptors passed in Intent");
14551        }
14552
14553        synchronized(this) {
14554            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14555        }
14556    }
14557
14558    @Override
14559    public IBinder peekService(Intent service, String resolvedType) {
14560        enforceNotIsolatedCaller("peekService");
14561        // Refuse possible leaked file descriptors
14562        if (service != null && service.hasFileDescriptors() == true) {
14563            throw new IllegalArgumentException("File descriptors passed in Intent");
14564        }
14565        synchronized(this) {
14566            return mServices.peekServiceLocked(service, resolvedType);
14567        }
14568    }
14569
14570    @Override
14571    public boolean stopServiceToken(ComponentName className, IBinder token,
14572            int startId) {
14573        synchronized(this) {
14574            return mServices.stopServiceTokenLocked(className, token, startId);
14575        }
14576    }
14577
14578    @Override
14579    public void setServiceForeground(ComponentName className, IBinder token,
14580            int id, Notification notification, boolean removeNotification) {
14581        synchronized(this) {
14582            mServices.setServiceForegroundLocked(className, token, id, notification,
14583                    removeNotification);
14584        }
14585    }
14586
14587    @Override
14588    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14589            boolean requireFull, String name, String callerPackage) {
14590        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14591                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14592    }
14593
14594    int unsafeConvertIncomingUser(int userId) {
14595        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14596                ? mCurrentUserId : userId;
14597    }
14598
14599    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14600            int allowMode, String name, String callerPackage) {
14601        final int callingUserId = UserHandle.getUserId(callingUid);
14602        if (callingUserId == userId) {
14603            return userId;
14604        }
14605
14606        // Note that we may be accessing mCurrentUserId outside of a lock...
14607        // shouldn't be a big deal, if this is being called outside
14608        // of a locked context there is intrinsically a race with
14609        // the value the caller will receive and someone else changing it.
14610        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14611        // we will switch to the calling user if access to the current user fails.
14612        int targetUserId = unsafeConvertIncomingUser(userId);
14613
14614        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14615            final boolean allow;
14616            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14617                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14618                // If the caller has this permission, they always pass go.  And collect $200.
14619                allow = true;
14620            } else if (allowMode == ALLOW_FULL_ONLY) {
14621                // We require full access, sucks to be you.
14622                allow = false;
14623            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14624                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14625                // If the caller does not have either permission, they are always doomed.
14626                allow = false;
14627            } else if (allowMode == ALLOW_NON_FULL) {
14628                // We are blanket allowing non-full access, you lucky caller!
14629                allow = true;
14630            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14631                // We may or may not allow this depending on whether the two users are
14632                // in the same profile.
14633                synchronized (mUserProfileGroupIdsSelfLocked) {
14634                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14635                            UserInfo.NO_PROFILE_GROUP_ID);
14636                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14637                            UserInfo.NO_PROFILE_GROUP_ID);
14638                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14639                            && callingProfile == targetProfile;
14640                }
14641            } else {
14642                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14643            }
14644            if (!allow) {
14645                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14646                    // In this case, they would like to just execute as their
14647                    // owner user instead of failing.
14648                    targetUserId = callingUserId;
14649                } else {
14650                    StringBuilder builder = new StringBuilder(128);
14651                    builder.append("Permission Denial: ");
14652                    builder.append(name);
14653                    if (callerPackage != null) {
14654                        builder.append(" from ");
14655                        builder.append(callerPackage);
14656                    }
14657                    builder.append(" asks to run as user ");
14658                    builder.append(userId);
14659                    builder.append(" but is calling from user ");
14660                    builder.append(UserHandle.getUserId(callingUid));
14661                    builder.append("; this requires ");
14662                    builder.append(INTERACT_ACROSS_USERS_FULL);
14663                    if (allowMode != ALLOW_FULL_ONLY) {
14664                        builder.append(" or ");
14665                        builder.append(INTERACT_ACROSS_USERS);
14666                    }
14667                    String msg = builder.toString();
14668                    Slog.w(TAG, msg);
14669                    throw new SecurityException(msg);
14670                }
14671            }
14672        }
14673        if (!allowAll && targetUserId < 0) {
14674            throw new IllegalArgumentException(
14675                    "Call does not support special user #" + targetUserId);
14676        }
14677        // Check shell permission
14678        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14679            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14680                    targetUserId)) {
14681                throw new SecurityException("Shell does not have permission to access user "
14682                        + targetUserId + "\n " + Debug.getCallers(3));
14683            }
14684        }
14685        return targetUserId;
14686    }
14687
14688    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14689            String className, int flags) {
14690        boolean result = false;
14691        // For apps that don't have pre-defined UIDs, check for permission
14692        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14693            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14694                if (ActivityManager.checkUidPermission(
14695                        INTERACT_ACROSS_USERS,
14696                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14697                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14698                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14699                            + " requests FLAG_SINGLE_USER, but app does not hold "
14700                            + INTERACT_ACROSS_USERS;
14701                    Slog.w(TAG, msg);
14702                    throw new SecurityException(msg);
14703                }
14704                // Permission passed
14705                result = true;
14706            }
14707        } else if ("system".equals(componentProcessName)) {
14708            result = true;
14709        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14710            // Phone app and persistent apps are allowed to export singleuser providers.
14711            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14712                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14713        }
14714        if (DEBUG_MU) {
14715            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14716                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14717        }
14718        return result;
14719    }
14720
14721    /**
14722     * Checks to see if the caller is in the same app as the singleton
14723     * component, or the component is in a special app. It allows special apps
14724     * to export singleton components but prevents exporting singleton
14725     * components for regular apps.
14726     */
14727    boolean isValidSingletonCall(int callingUid, int componentUid) {
14728        int componentAppId = UserHandle.getAppId(componentUid);
14729        return UserHandle.isSameApp(callingUid, componentUid)
14730                || componentAppId == Process.SYSTEM_UID
14731                || componentAppId == Process.PHONE_UID
14732                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14733                        == PackageManager.PERMISSION_GRANTED;
14734    }
14735
14736    public int bindService(IApplicationThread caller, IBinder token,
14737            Intent service, String resolvedType,
14738            IServiceConnection connection, int flags, int userId) {
14739        enforceNotIsolatedCaller("bindService");
14740
14741        // Refuse possible leaked file descriptors
14742        if (service != null && service.hasFileDescriptors() == true) {
14743            throw new IllegalArgumentException("File descriptors passed in Intent");
14744        }
14745
14746        synchronized(this) {
14747            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14748                    connection, flags, userId);
14749        }
14750    }
14751
14752    public boolean unbindService(IServiceConnection connection) {
14753        synchronized (this) {
14754            return mServices.unbindServiceLocked(connection);
14755        }
14756    }
14757
14758    public void publishService(IBinder token, Intent intent, IBinder service) {
14759        // Refuse possible leaked file descriptors
14760        if (intent != null && intent.hasFileDescriptors() == true) {
14761            throw new IllegalArgumentException("File descriptors passed in Intent");
14762        }
14763
14764        synchronized(this) {
14765            if (!(token instanceof ServiceRecord)) {
14766                throw new IllegalArgumentException("Invalid service token");
14767            }
14768            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14769        }
14770    }
14771
14772    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14773        // Refuse possible leaked file descriptors
14774        if (intent != null && intent.hasFileDescriptors() == true) {
14775            throw new IllegalArgumentException("File descriptors passed in Intent");
14776        }
14777
14778        synchronized(this) {
14779            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14780        }
14781    }
14782
14783    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14784        synchronized(this) {
14785            if (!(token instanceof ServiceRecord)) {
14786                throw new IllegalArgumentException("Invalid service token");
14787            }
14788            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14789        }
14790    }
14791
14792    // =========================================================
14793    // BACKUP AND RESTORE
14794    // =========================================================
14795
14796    // Cause the target app to be launched if necessary and its backup agent
14797    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14798    // activity manager to announce its creation.
14799    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14800        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14801        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14802
14803        synchronized(this) {
14804            // !!! TODO: currently no check here that we're already bound
14805            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14806            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14807            synchronized (stats) {
14808                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14809            }
14810
14811            // Backup agent is now in use, its package can't be stopped.
14812            try {
14813                AppGlobals.getPackageManager().setPackageStoppedState(
14814                        app.packageName, false, UserHandle.getUserId(app.uid));
14815            } catch (RemoteException e) {
14816            } catch (IllegalArgumentException e) {
14817                Slog.w(TAG, "Failed trying to unstop package "
14818                        + app.packageName + ": " + e);
14819            }
14820
14821            BackupRecord r = new BackupRecord(ss, app, backupMode);
14822            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14823                    ? new ComponentName(app.packageName, app.backupAgentName)
14824                    : new ComponentName("android", "FullBackupAgent");
14825            // startProcessLocked() returns existing proc's record if it's already running
14826            ProcessRecord proc = startProcessLocked(app.processName, app,
14827                    false, 0, "backup", hostingName, false, false, false);
14828            if (proc == null) {
14829                Slog.e(TAG, "Unable to start backup agent process " + r);
14830                return false;
14831            }
14832
14833            r.app = proc;
14834            mBackupTarget = r;
14835            mBackupAppName = app.packageName;
14836
14837            // Try not to kill the process during backup
14838            updateOomAdjLocked(proc);
14839
14840            // If the process is already attached, schedule the creation of the backup agent now.
14841            // If it is not yet live, this will be done when it attaches to the framework.
14842            if (proc.thread != null) {
14843                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14844                try {
14845                    proc.thread.scheduleCreateBackupAgent(app,
14846                            compatibilityInfoForPackageLocked(app), backupMode);
14847                } catch (RemoteException e) {
14848                    // Will time out on the backup manager side
14849                }
14850            } else {
14851                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14852            }
14853            // Invariants: at this point, the target app process exists and the application
14854            // is either already running or in the process of coming up.  mBackupTarget and
14855            // mBackupAppName describe the app, so that when it binds back to the AM we
14856            // know that it's scheduled for a backup-agent operation.
14857        }
14858
14859        return true;
14860    }
14861
14862    @Override
14863    public void clearPendingBackup() {
14864        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14865        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14866
14867        synchronized (this) {
14868            mBackupTarget = null;
14869            mBackupAppName = null;
14870        }
14871    }
14872
14873    // A backup agent has just come up
14874    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14875        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14876                + " = " + agent);
14877
14878        synchronized(this) {
14879            if (!agentPackageName.equals(mBackupAppName)) {
14880                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14881                return;
14882            }
14883        }
14884
14885        long oldIdent = Binder.clearCallingIdentity();
14886        try {
14887            IBackupManager bm = IBackupManager.Stub.asInterface(
14888                    ServiceManager.getService(Context.BACKUP_SERVICE));
14889            bm.agentConnected(agentPackageName, agent);
14890        } catch (RemoteException e) {
14891            // can't happen; the backup manager service is local
14892        } catch (Exception e) {
14893            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14894            e.printStackTrace();
14895        } finally {
14896            Binder.restoreCallingIdentity(oldIdent);
14897        }
14898    }
14899
14900    // done with this agent
14901    public void unbindBackupAgent(ApplicationInfo appInfo) {
14902        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14903        if (appInfo == null) {
14904            Slog.w(TAG, "unbind backup agent for null app");
14905            return;
14906        }
14907
14908        synchronized(this) {
14909            try {
14910                if (mBackupAppName == null) {
14911                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14912                    return;
14913                }
14914
14915                if (!mBackupAppName.equals(appInfo.packageName)) {
14916                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14917                    return;
14918                }
14919
14920                // Not backing this app up any more; reset its OOM adjustment
14921                final ProcessRecord proc = mBackupTarget.app;
14922                updateOomAdjLocked(proc);
14923
14924                // If the app crashed during backup, 'thread' will be null here
14925                if (proc.thread != null) {
14926                    try {
14927                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14928                                compatibilityInfoForPackageLocked(appInfo));
14929                    } catch (Exception e) {
14930                        Slog.e(TAG, "Exception when unbinding backup agent:");
14931                        e.printStackTrace();
14932                    }
14933                }
14934            } finally {
14935                mBackupTarget = null;
14936                mBackupAppName = null;
14937            }
14938        }
14939    }
14940    // =========================================================
14941    // BROADCASTS
14942    // =========================================================
14943
14944    private final List getStickiesLocked(String action, IntentFilter filter,
14945            List cur, int userId) {
14946        final ContentResolver resolver = mContext.getContentResolver();
14947        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14948        if (stickies == null) {
14949            return cur;
14950        }
14951        final ArrayList<Intent> list = stickies.get(action);
14952        if (list == null) {
14953            return cur;
14954        }
14955        int N = list.size();
14956        for (int i=0; i<N; i++) {
14957            Intent intent = list.get(i);
14958            if (filter.match(resolver, intent, true, TAG) >= 0) {
14959                if (cur == null) {
14960                    cur = new ArrayList<Intent>();
14961                }
14962                cur.add(intent);
14963            }
14964        }
14965        return cur;
14966    }
14967
14968    boolean isPendingBroadcastProcessLocked(int pid) {
14969        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14970                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14971    }
14972
14973    void skipPendingBroadcastLocked(int pid) {
14974            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14975            for (BroadcastQueue queue : mBroadcastQueues) {
14976                queue.skipPendingBroadcastLocked(pid);
14977            }
14978    }
14979
14980    // The app just attached; send any pending broadcasts that it should receive
14981    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14982        boolean didSomething = false;
14983        for (BroadcastQueue queue : mBroadcastQueues) {
14984            didSomething |= queue.sendPendingBroadcastsLocked(app);
14985        }
14986        return didSomething;
14987    }
14988
14989    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14990            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14991        enforceNotIsolatedCaller("registerReceiver");
14992        int callingUid;
14993        int callingPid;
14994        synchronized(this) {
14995            ProcessRecord callerApp = null;
14996            if (caller != null) {
14997                callerApp = getRecordForAppLocked(caller);
14998                if (callerApp == null) {
14999                    throw new SecurityException(
15000                            "Unable to find app for caller " + caller
15001                            + " (pid=" + Binder.getCallingPid()
15002                            + ") when registering receiver " + receiver);
15003                }
15004                if (callerApp.info.uid != Process.SYSTEM_UID &&
15005                        !callerApp.pkgList.containsKey(callerPackage) &&
15006                        !"android".equals(callerPackage)) {
15007                    throw new SecurityException("Given caller package " + callerPackage
15008                            + " is not running in process " + callerApp);
15009                }
15010                callingUid = callerApp.info.uid;
15011                callingPid = callerApp.pid;
15012            } else {
15013                callerPackage = null;
15014                callingUid = Binder.getCallingUid();
15015                callingPid = Binder.getCallingPid();
15016            }
15017
15018            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15019                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15020
15021            List allSticky = null;
15022
15023            // Look for any matching sticky broadcasts...
15024            Iterator actions = filter.actionsIterator();
15025            if (actions != null) {
15026                while (actions.hasNext()) {
15027                    String action = (String)actions.next();
15028                    allSticky = getStickiesLocked(action, filter, allSticky,
15029                            UserHandle.USER_ALL);
15030                    allSticky = getStickiesLocked(action, filter, allSticky,
15031                            UserHandle.getUserId(callingUid));
15032                }
15033            } else {
15034                allSticky = getStickiesLocked(null, filter, allSticky,
15035                        UserHandle.USER_ALL);
15036                allSticky = getStickiesLocked(null, filter, allSticky,
15037                        UserHandle.getUserId(callingUid));
15038            }
15039
15040            // The first sticky in the list is returned directly back to
15041            // the client.
15042            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15043
15044            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15045                    + ": " + sticky);
15046
15047            if (receiver == null) {
15048                return sticky;
15049            }
15050
15051            ReceiverList rl
15052                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15053            if (rl == null) {
15054                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15055                        userId, receiver);
15056                if (rl.app != null) {
15057                    rl.app.receivers.add(rl);
15058                } else {
15059                    try {
15060                        receiver.asBinder().linkToDeath(rl, 0);
15061                    } catch (RemoteException e) {
15062                        return sticky;
15063                    }
15064                    rl.linkedToDeath = true;
15065                }
15066                mRegisteredReceivers.put(receiver.asBinder(), rl);
15067            } else if (rl.uid != callingUid) {
15068                throw new IllegalArgumentException(
15069                        "Receiver requested to register for uid " + callingUid
15070                        + " was previously registered for uid " + rl.uid);
15071            } else if (rl.pid != callingPid) {
15072                throw new IllegalArgumentException(
15073                        "Receiver requested to register for pid " + callingPid
15074                        + " was previously registered for pid " + rl.pid);
15075            } else if (rl.userId != userId) {
15076                throw new IllegalArgumentException(
15077                        "Receiver requested to register for user " + userId
15078                        + " was previously registered for user " + rl.userId);
15079            }
15080            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15081                    permission, callingUid, userId);
15082            rl.add(bf);
15083            if (!bf.debugCheck()) {
15084                Slog.w(TAG, "==> For Dynamic broadast");
15085            }
15086            mReceiverResolver.addFilter(bf);
15087
15088            // Enqueue broadcasts for all existing stickies that match
15089            // this filter.
15090            if (allSticky != null) {
15091                ArrayList receivers = new ArrayList();
15092                receivers.add(bf);
15093
15094                int N = allSticky.size();
15095                for (int i=0; i<N; i++) {
15096                    Intent intent = (Intent)allSticky.get(i);
15097                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15098                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15099                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15100                            null, null, false, true, true, -1);
15101                    queue.enqueueParallelBroadcastLocked(r);
15102                    queue.scheduleBroadcastsLocked();
15103                }
15104            }
15105
15106            return sticky;
15107        }
15108    }
15109
15110    public void unregisterReceiver(IIntentReceiver receiver) {
15111        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15112
15113        final long origId = Binder.clearCallingIdentity();
15114        try {
15115            boolean doTrim = false;
15116
15117            synchronized(this) {
15118                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15119                if (rl != null) {
15120                    if (rl.curBroadcast != null) {
15121                        BroadcastRecord r = rl.curBroadcast;
15122                        final boolean doNext = finishReceiverLocked(
15123                                receiver.asBinder(), r.resultCode, r.resultData,
15124                                r.resultExtras, r.resultAbort);
15125                        if (doNext) {
15126                            doTrim = true;
15127                            r.queue.processNextBroadcast(false);
15128                        }
15129                    }
15130
15131                    if (rl.app != null) {
15132                        rl.app.receivers.remove(rl);
15133                    }
15134                    removeReceiverLocked(rl);
15135                    if (rl.linkedToDeath) {
15136                        rl.linkedToDeath = false;
15137                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15138                    }
15139                }
15140            }
15141
15142            // If we actually concluded any broadcasts, we might now be able
15143            // to trim the recipients' apps from our working set
15144            if (doTrim) {
15145                trimApplications();
15146                return;
15147            }
15148
15149        } finally {
15150            Binder.restoreCallingIdentity(origId);
15151        }
15152    }
15153
15154    void removeReceiverLocked(ReceiverList rl) {
15155        mRegisteredReceivers.remove(rl.receiver.asBinder());
15156        int N = rl.size();
15157        for (int i=0; i<N; i++) {
15158            mReceiverResolver.removeFilter(rl.get(i));
15159        }
15160    }
15161
15162    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15163        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15164            ProcessRecord r = mLruProcesses.get(i);
15165            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15166                try {
15167                    r.thread.dispatchPackageBroadcast(cmd, packages);
15168                } catch (RemoteException ex) {
15169                }
15170            }
15171        }
15172    }
15173
15174    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15175            int callingUid, int[] users) {
15176        List<ResolveInfo> receivers = null;
15177        try {
15178            HashSet<ComponentName> singleUserReceivers = null;
15179            boolean scannedFirstReceivers = false;
15180            for (int user : users) {
15181                // Skip users that have Shell restrictions
15182                if (callingUid == Process.SHELL_UID
15183                        && getUserManagerLocked().hasUserRestriction(
15184                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15185                    continue;
15186                }
15187                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15188                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15189                if (user != 0 && newReceivers != null) {
15190                    // If this is not the primary user, we need to check for
15191                    // any receivers that should be filtered out.
15192                    for (int i=0; i<newReceivers.size(); i++) {
15193                        ResolveInfo ri = newReceivers.get(i);
15194                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15195                            newReceivers.remove(i);
15196                            i--;
15197                        }
15198                    }
15199                }
15200                if (newReceivers != null && newReceivers.size() == 0) {
15201                    newReceivers = null;
15202                }
15203                if (receivers == null) {
15204                    receivers = newReceivers;
15205                } else if (newReceivers != null) {
15206                    // We need to concatenate the additional receivers
15207                    // found with what we have do far.  This would be easy,
15208                    // but we also need to de-dup any receivers that are
15209                    // singleUser.
15210                    if (!scannedFirstReceivers) {
15211                        // Collect any single user receivers we had already retrieved.
15212                        scannedFirstReceivers = true;
15213                        for (int i=0; i<receivers.size(); i++) {
15214                            ResolveInfo ri = receivers.get(i);
15215                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15216                                ComponentName cn = new ComponentName(
15217                                        ri.activityInfo.packageName, ri.activityInfo.name);
15218                                if (singleUserReceivers == null) {
15219                                    singleUserReceivers = new HashSet<ComponentName>();
15220                                }
15221                                singleUserReceivers.add(cn);
15222                            }
15223                        }
15224                    }
15225                    // Add the new results to the existing results, tracking
15226                    // and de-dupping single user receivers.
15227                    for (int i=0; i<newReceivers.size(); i++) {
15228                        ResolveInfo ri = newReceivers.get(i);
15229                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15230                            ComponentName cn = new ComponentName(
15231                                    ri.activityInfo.packageName, ri.activityInfo.name);
15232                            if (singleUserReceivers == null) {
15233                                singleUserReceivers = new HashSet<ComponentName>();
15234                            }
15235                            if (!singleUserReceivers.contains(cn)) {
15236                                singleUserReceivers.add(cn);
15237                                receivers.add(ri);
15238                            }
15239                        } else {
15240                            receivers.add(ri);
15241                        }
15242                    }
15243                }
15244            }
15245        } catch (RemoteException ex) {
15246            // pm is in same process, this will never happen.
15247        }
15248        return receivers;
15249    }
15250
15251    private final int broadcastIntentLocked(ProcessRecord callerApp,
15252            String callerPackage, Intent intent, String resolvedType,
15253            IIntentReceiver resultTo, int resultCode, String resultData,
15254            Bundle map, String requiredPermission, int appOp,
15255            boolean ordered, boolean sticky, int callingPid, int callingUid,
15256            int userId) {
15257        intent = new Intent(intent);
15258
15259        // By default broadcasts do not go to stopped apps.
15260        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15261
15262        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15263            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15264            + " ordered=" + ordered + " userid=" + userId);
15265        if ((resultTo != null) && !ordered) {
15266            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15267        }
15268
15269        userId = handleIncomingUser(callingPid, callingUid, userId,
15270                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15271
15272        // Make sure that the user who is receiving this broadcast is started.
15273        // If not, we will just skip it.
15274
15275        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15276            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15277                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15278                Slog.w(TAG, "Skipping broadcast of " + intent
15279                        + ": user " + userId + " is stopped");
15280                return ActivityManager.BROADCAST_SUCCESS;
15281            }
15282        }
15283
15284        /*
15285         * Prevent non-system code (defined here to be non-persistent
15286         * processes) from sending protected broadcasts.
15287         */
15288        int callingAppId = UserHandle.getAppId(callingUid);
15289        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15290            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15291            || callingAppId == Process.NFC_UID || callingUid == 0) {
15292            // Always okay.
15293        } else if (callerApp == null || !callerApp.persistent) {
15294            try {
15295                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15296                        intent.getAction())) {
15297                    String msg = "Permission Denial: not allowed to send broadcast "
15298                            + intent.getAction() + " from pid="
15299                            + callingPid + ", uid=" + callingUid;
15300                    Slog.w(TAG, msg);
15301                    throw new SecurityException(msg);
15302                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15303                    // Special case for compatibility: we don't want apps to send this,
15304                    // but historically it has not been protected and apps may be using it
15305                    // to poke their own app widget.  So, instead of making it protected,
15306                    // just limit it to the caller.
15307                    if (callerApp == null) {
15308                        String msg = "Permission Denial: not allowed to send broadcast "
15309                                + intent.getAction() + " from unknown caller.";
15310                        Slog.w(TAG, msg);
15311                        throw new SecurityException(msg);
15312                    } else if (intent.getComponent() != null) {
15313                        // They are good enough to send to an explicit component...  verify
15314                        // it is being sent to the calling app.
15315                        if (!intent.getComponent().getPackageName().equals(
15316                                callerApp.info.packageName)) {
15317                            String msg = "Permission Denial: not allowed to send broadcast "
15318                                    + intent.getAction() + " to "
15319                                    + intent.getComponent().getPackageName() + " from "
15320                                    + callerApp.info.packageName;
15321                            Slog.w(TAG, msg);
15322                            throw new SecurityException(msg);
15323                        }
15324                    } else {
15325                        // Limit broadcast to their own package.
15326                        intent.setPackage(callerApp.info.packageName);
15327                    }
15328                }
15329            } catch (RemoteException e) {
15330                Slog.w(TAG, "Remote exception", e);
15331                return ActivityManager.BROADCAST_SUCCESS;
15332            }
15333        }
15334
15335        // Handle special intents: if this broadcast is from the package
15336        // manager about a package being removed, we need to remove all of
15337        // its activities from the history stack.
15338        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15339                intent.getAction());
15340        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15341                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15342                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15343                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15344                || uidRemoved) {
15345            if (checkComponentPermission(
15346                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15347                    callingPid, callingUid, -1, true)
15348                    == PackageManager.PERMISSION_GRANTED) {
15349                if (uidRemoved) {
15350                    final Bundle intentExtras = intent.getExtras();
15351                    final int uid = intentExtras != null
15352                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15353                    if (uid >= 0) {
15354                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15355                        synchronized (bs) {
15356                            bs.removeUidStatsLocked(uid);
15357                        }
15358                        mAppOpsService.uidRemoved(uid);
15359                    }
15360                } else {
15361                    // If resources are unavailable just force stop all
15362                    // those packages and flush the attribute cache as well.
15363                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15364                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15365                        if (list != null && (list.length > 0)) {
15366                            for (String pkg : list) {
15367                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15368                                        "storage unmount");
15369                            }
15370                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15371                            sendPackageBroadcastLocked(
15372                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15373                        }
15374                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15375                            intent.getAction())) {
15376                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15377                    } else {
15378                        Uri data = intent.getData();
15379                        String ssp;
15380                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15381                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15382                                    intent.getAction());
15383                            boolean fullUninstall = removed &&
15384                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15385                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15386                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15387                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15388                                        false, fullUninstall, userId,
15389                                        removed ? "pkg removed" : "pkg changed");
15390                            }
15391                            if (removed) {
15392                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15393                                        new String[] {ssp}, userId);
15394                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15395                                    mAppOpsService.packageRemoved(
15396                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15397
15398                                    // Remove all permissions granted from/to this package
15399                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15400                                }
15401                            }
15402                        }
15403                    }
15404                }
15405            } else {
15406                String msg = "Permission Denial: " + intent.getAction()
15407                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15408                        + ", uid=" + callingUid + ")"
15409                        + " requires "
15410                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15411                Slog.w(TAG, msg);
15412                throw new SecurityException(msg);
15413            }
15414
15415        // Special case for adding a package: by default turn on compatibility
15416        // mode.
15417        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15418            Uri data = intent.getData();
15419            String ssp;
15420            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15421                mCompatModePackages.handlePackageAddedLocked(ssp,
15422                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15423            }
15424        }
15425
15426        /*
15427         * If this is the time zone changed action, queue up a message that will reset the timezone
15428         * of all currently running processes. This message will get queued up before the broadcast
15429         * happens.
15430         */
15431        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15432            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15433        }
15434
15435        /*
15436         * If the user set the time, let all running processes know.
15437         */
15438        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15439            final int is24Hour = intent.getBooleanExtra(
15440                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15441            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15442            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15443            synchronized (stats) {
15444                stats.noteCurrentTimeChangedLocked();
15445            }
15446        }
15447
15448        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15449            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15450        }
15451
15452        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15453            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15454            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15455        }
15456
15457        // Add to the sticky list if requested.
15458        if (sticky) {
15459            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15460                    callingPid, callingUid)
15461                    != PackageManager.PERMISSION_GRANTED) {
15462                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15463                        + callingPid + ", uid=" + callingUid
15464                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15465                Slog.w(TAG, msg);
15466                throw new SecurityException(msg);
15467            }
15468            if (requiredPermission != null) {
15469                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15470                        + " and enforce permission " + requiredPermission);
15471                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15472            }
15473            if (intent.getComponent() != null) {
15474                throw new SecurityException(
15475                        "Sticky broadcasts can't target a specific component");
15476            }
15477            // We use userId directly here, since the "all" target is maintained
15478            // as a separate set of sticky broadcasts.
15479            if (userId != UserHandle.USER_ALL) {
15480                // But first, if this is not a broadcast to all users, then
15481                // make sure it doesn't conflict with an existing broadcast to
15482                // all users.
15483                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15484                        UserHandle.USER_ALL);
15485                if (stickies != null) {
15486                    ArrayList<Intent> list = stickies.get(intent.getAction());
15487                    if (list != null) {
15488                        int N = list.size();
15489                        int i;
15490                        for (i=0; i<N; i++) {
15491                            if (intent.filterEquals(list.get(i))) {
15492                                throw new IllegalArgumentException(
15493                                        "Sticky broadcast " + intent + " for user "
15494                                        + userId + " conflicts with existing global broadcast");
15495                            }
15496                        }
15497                    }
15498                }
15499            }
15500            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15501            if (stickies == null) {
15502                stickies = new ArrayMap<String, ArrayList<Intent>>();
15503                mStickyBroadcasts.put(userId, stickies);
15504            }
15505            ArrayList<Intent> list = stickies.get(intent.getAction());
15506            if (list == null) {
15507                list = new ArrayList<Intent>();
15508                stickies.put(intent.getAction(), list);
15509            }
15510            int N = list.size();
15511            int i;
15512            for (i=0; i<N; i++) {
15513                if (intent.filterEquals(list.get(i))) {
15514                    // This sticky already exists, replace it.
15515                    list.set(i, new Intent(intent));
15516                    break;
15517                }
15518            }
15519            if (i >= N) {
15520                list.add(new Intent(intent));
15521            }
15522        }
15523
15524        int[] users;
15525        if (userId == UserHandle.USER_ALL) {
15526            // Caller wants broadcast to go to all started users.
15527            users = mStartedUserArray;
15528        } else {
15529            // Caller wants broadcast to go to one specific user.
15530            users = new int[] {userId};
15531        }
15532
15533        // Figure out who all will receive this broadcast.
15534        List receivers = null;
15535        List<BroadcastFilter> registeredReceivers = null;
15536        // Need to resolve the intent to interested receivers...
15537        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15538                 == 0) {
15539            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15540        }
15541        if (intent.getComponent() == null) {
15542            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15543                // Query one target user at a time, excluding shell-restricted users
15544                UserManagerService ums = getUserManagerLocked();
15545                for (int i = 0; i < users.length; i++) {
15546                    if (ums.hasUserRestriction(
15547                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15548                        continue;
15549                    }
15550                    List<BroadcastFilter> registeredReceiversForUser =
15551                            mReceiverResolver.queryIntent(intent,
15552                                    resolvedType, false, users[i]);
15553                    if (registeredReceivers == null) {
15554                        registeredReceivers = registeredReceiversForUser;
15555                    } else if (registeredReceiversForUser != null) {
15556                        registeredReceivers.addAll(registeredReceiversForUser);
15557                    }
15558                }
15559            } else {
15560                registeredReceivers = mReceiverResolver.queryIntent(intent,
15561                        resolvedType, false, userId);
15562            }
15563        }
15564
15565        final boolean replacePending =
15566                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15567
15568        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15569                + " replacePending=" + replacePending);
15570
15571        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15572        if (!ordered && NR > 0) {
15573            // If we are not serializing this broadcast, then send the
15574            // registered receivers separately so they don't wait for the
15575            // components to be launched.
15576            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15577            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15578                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15579                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15580                    ordered, sticky, false, userId);
15581            if (DEBUG_BROADCAST) Slog.v(
15582                    TAG, "Enqueueing parallel broadcast " + r);
15583            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15584            if (!replaced) {
15585                queue.enqueueParallelBroadcastLocked(r);
15586                queue.scheduleBroadcastsLocked();
15587            }
15588            registeredReceivers = null;
15589            NR = 0;
15590        }
15591
15592        // Merge into one list.
15593        int ir = 0;
15594        if (receivers != null) {
15595            // A special case for PACKAGE_ADDED: do not allow the package
15596            // being added to see this broadcast.  This prevents them from
15597            // using this as a back door to get run as soon as they are
15598            // installed.  Maybe in the future we want to have a special install
15599            // broadcast or such for apps, but we'd like to deliberately make
15600            // this decision.
15601            String skipPackages[] = null;
15602            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15603                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15604                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15605                Uri data = intent.getData();
15606                if (data != null) {
15607                    String pkgName = data.getSchemeSpecificPart();
15608                    if (pkgName != null) {
15609                        skipPackages = new String[] { pkgName };
15610                    }
15611                }
15612            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15613                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15614            }
15615            if (skipPackages != null && (skipPackages.length > 0)) {
15616                for (String skipPackage : skipPackages) {
15617                    if (skipPackage != null) {
15618                        int NT = receivers.size();
15619                        for (int it=0; it<NT; it++) {
15620                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15621                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15622                                receivers.remove(it);
15623                                it--;
15624                                NT--;
15625                            }
15626                        }
15627                    }
15628                }
15629            }
15630
15631            int NT = receivers != null ? receivers.size() : 0;
15632            int it = 0;
15633            ResolveInfo curt = null;
15634            BroadcastFilter curr = null;
15635            while (it < NT && ir < NR) {
15636                if (curt == null) {
15637                    curt = (ResolveInfo)receivers.get(it);
15638                }
15639                if (curr == null) {
15640                    curr = registeredReceivers.get(ir);
15641                }
15642                if (curr.getPriority() >= curt.priority) {
15643                    // Insert this broadcast record into the final list.
15644                    receivers.add(it, curr);
15645                    ir++;
15646                    curr = null;
15647                    it++;
15648                    NT++;
15649                } else {
15650                    // Skip to the next ResolveInfo in the final list.
15651                    it++;
15652                    curt = null;
15653                }
15654            }
15655        }
15656        while (ir < NR) {
15657            if (receivers == null) {
15658                receivers = new ArrayList();
15659            }
15660            receivers.add(registeredReceivers.get(ir));
15661            ir++;
15662        }
15663
15664        if ((receivers != null && receivers.size() > 0)
15665                || resultTo != null) {
15666            BroadcastQueue queue = broadcastQueueForIntent(intent);
15667            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15668                    callerPackage, callingPid, callingUid, resolvedType,
15669                    requiredPermission, appOp, receivers, resultTo, resultCode,
15670                    resultData, map, ordered, sticky, false, userId);
15671            if (DEBUG_BROADCAST) Slog.v(
15672                    TAG, "Enqueueing ordered broadcast " + r
15673                    + ": prev had " + queue.mOrderedBroadcasts.size());
15674            if (DEBUG_BROADCAST) {
15675                int seq = r.intent.getIntExtra("seq", -1);
15676                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15677            }
15678            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15679            if (!replaced) {
15680                queue.enqueueOrderedBroadcastLocked(r);
15681                queue.scheduleBroadcastsLocked();
15682            }
15683        }
15684
15685        return ActivityManager.BROADCAST_SUCCESS;
15686    }
15687
15688    final Intent verifyBroadcastLocked(Intent intent) {
15689        // Refuse possible leaked file descriptors
15690        if (intent != null && intent.hasFileDescriptors() == true) {
15691            throw new IllegalArgumentException("File descriptors passed in Intent");
15692        }
15693
15694        int flags = intent.getFlags();
15695
15696        if (!mProcessesReady) {
15697            // if the caller really truly claims to know what they're doing, go
15698            // ahead and allow the broadcast without launching any receivers
15699            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15700                intent = new Intent(intent);
15701                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15702            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15703                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15704                        + " before boot completion");
15705                throw new IllegalStateException("Cannot broadcast before boot completed");
15706            }
15707        }
15708
15709        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15710            throw new IllegalArgumentException(
15711                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15712        }
15713
15714        return intent;
15715    }
15716
15717    public final int broadcastIntent(IApplicationThread caller,
15718            Intent intent, String resolvedType, IIntentReceiver resultTo,
15719            int resultCode, String resultData, Bundle map,
15720            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15721        enforceNotIsolatedCaller("broadcastIntent");
15722        synchronized(this) {
15723            intent = verifyBroadcastLocked(intent);
15724
15725            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15726            final int callingPid = Binder.getCallingPid();
15727            final int callingUid = Binder.getCallingUid();
15728            final long origId = Binder.clearCallingIdentity();
15729            int res = broadcastIntentLocked(callerApp,
15730                    callerApp != null ? callerApp.info.packageName : null,
15731                    intent, resolvedType, resultTo,
15732                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15733                    callingPid, callingUid, userId);
15734            Binder.restoreCallingIdentity(origId);
15735            return res;
15736        }
15737    }
15738
15739    int broadcastIntentInPackage(String packageName, int uid,
15740            Intent intent, String resolvedType, IIntentReceiver resultTo,
15741            int resultCode, String resultData, Bundle map,
15742            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15743        synchronized(this) {
15744            intent = verifyBroadcastLocked(intent);
15745
15746            final long origId = Binder.clearCallingIdentity();
15747            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15748                    resultTo, resultCode, resultData, map, requiredPermission,
15749                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15750            Binder.restoreCallingIdentity(origId);
15751            return res;
15752        }
15753    }
15754
15755    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15756        // Refuse possible leaked file descriptors
15757        if (intent != null && intent.hasFileDescriptors() == true) {
15758            throw new IllegalArgumentException("File descriptors passed in Intent");
15759        }
15760
15761        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15762                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15763
15764        synchronized(this) {
15765            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15766                    != PackageManager.PERMISSION_GRANTED) {
15767                String msg = "Permission Denial: unbroadcastIntent() from pid="
15768                        + Binder.getCallingPid()
15769                        + ", uid=" + Binder.getCallingUid()
15770                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15771                Slog.w(TAG, msg);
15772                throw new SecurityException(msg);
15773            }
15774            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15775            if (stickies != null) {
15776                ArrayList<Intent> list = stickies.get(intent.getAction());
15777                if (list != null) {
15778                    int N = list.size();
15779                    int i;
15780                    for (i=0; i<N; i++) {
15781                        if (intent.filterEquals(list.get(i))) {
15782                            list.remove(i);
15783                            break;
15784                        }
15785                    }
15786                    if (list.size() <= 0) {
15787                        stickies.remove(intent.getAction());
15788                    }
15789                }
15790                if (stickies.size() <= 0) {
15791                    mStickyBroadcasts.remove(userId);
15792                }
15793            }
15794        }
15795    }
15796
15797    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15798            String resultData, Bundle resultExtras, boolean resultAbort) {
15799        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15800        if (r == null) {
15801            Slog.w(TAG, "finishReceiver called but not found on queue");
15802            return false;
15803        }
15804
15805        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15806    }
15807
15808    void backgroundServicesFinishedLocked(int userId) {
15809        for (BroadcastQueue queue : mBroadcastQueues) {
15810            queue.backgroundServicesFinishedLocked(userId);
15811        }
15812    }
15813
15814    public void finishReceiver(IBinder who, int resultCode, String resultData,
15815            Bundle resultExtras, boolean resultAbort) {
15816        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15817
15818        // Refuse possible leaked file descriptors
15819        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15820            throw new IllegalArgumentException("File descriptors passed in Bundle");
15821        }
15822
15823        final long origId = Binder.clearCallingIdentity();
15824        try {
15825            boolean doNext = false;
15826            BroadcastRecord r;
15827
15828            synchronized(this) {
15829                r = broadcastRecordForReceiverLocked(who);
15830                if (r != null) {
15831                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15832                        resultData, resultExtras, resultAbort, true);
15833                }
15834            }
15835
15836            if (doNext) {
15837                r.queue.processNextBroadcast(false);
15838            }
15839            trimApplications();
15840        } finally {
15841            Binder.restoreCallingIdentity(origId);
15842        }
15843    }
15844
15845    // =========================================================
15846    // INSTRUMENTATION
15847    // =========================================================
15848
15849    public boolean startInstrumentation(ComponentName className,
15850            String profileFile, int flags, Bundle arguments,
15851            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15852            int userId, String abiOverride) {
15853        enforceNotIsolatedCaller("startInstrumentation");
15854        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15855                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15856        // Refuse possible leaked file descriptors
15857        if (arguments != null && arguments.hasFileDescriptors()) {
15858            throw new IllegalArgumentException("File descriptors passed in Bundle");
15859        }
15860
15861        synchronized(this) {
15862            InstrumentationInfo ii = null;
15863            ApplicationInfo ai = null;
15864            try {
15865                ii = mContext.getPackageManager().getInstrumentationInfo(
15866                    className, STOCK_PM_FLAGS);
15867                ai = AppGlobals.getPackageManager().getApplicationInfo(
15868                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15869            } catch (PackageManager.NameNotFoundException e) {
15870            } catch (RemoteException e) {
15871            }
15872            if (ii == null) {
15873                reportStartInstrumentationFailure(watcher, className,
15874                        "Unable to find instrumentation info for: " + className);
15875                return false;
15876            }
15877            if (ai == null) {
15878                reportStartInstrumentationFailure(watcher, className,
15879                        "Unable to find instrumentation target package: " + ii.targetPackage);
15880                return false;
15881            }
15882
15883            int match = mContext.getPackageManager().checkSignatures(
15884                    ii.targetPackage, ii.packageName);
15885            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15886                String msg = "Permission Denial: starting instrumentation "
15887                        + className + " from pid="
15888                        + Binder.getCallingPid()
15889                        + ", uid=" + Binder.getCallingPid()
15890                        + " not allowed because package " + ii.packageName
15891                        + " does not have a signature matching the target "
15892                        + ii.targetPackage;
15893                reportStartInstrumentationFailure(watcher, className, msg);
15894                throw new SecurityException(msg);
15895            }
15896
15897            final long origId = Binder.clearCallingIdentity();
15898            // Instrumentation can kill and relaunch even persistent processes
15899            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15900                    "start instr");
15901            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15902            app.instrumentationClass = className;
15903            app.instrumentationInfo = ai;
15904            app.instrumentationProfileFile = profileFile;
15905            app.instrumentationArguments = arguments;
15906            app.instrumentationWatcher = watcher;
15907            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15908            app.instrumentationResultClass = className;
15909            Binder.restoreCallingIdentity(origId);
15910        }
15911
15912        return true;
15913    }
15914
15915    /**
15916     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15917     * error to the logs, but if somebody is watching, send the report there too.  This enables
15918     * the "am" command to report errors with more information.
15919     *
15920     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15921     * @param cn The component name of the instrumentation.
15922     * @param report The error report.
15923     */
15924    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15925            ComponentName cn, String report) {
15926        Slog.w(TAG, report);
15927        try {
15928            if (watcher != null) {
15929                Bundle results = new Bundle();
15930                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15931                results.putString("Error", report);
15932                watcher.instrumentationStatus(cn, -1, results);
15933            }
15934        } catch (RemoteException e) {
15935            Slog.w(TAG, e);
15936        }
15937    }
15938
15939    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15940        if (app.instrumentationWatcher != null) {
15941            try {
15942                // NOTE:  IInstrumentationWatcher *must* be oneway here
15943                app.instrumentationWatcher.instrumentationFinished(
15944                    app.instrumentationClass,
15945                    resultCode,
15946                    results);
15947            } catch (RemoteException e) {
15948            }
15949        }
15950        if (app.instrumentationUiAutomationConnection != null) {
15951            try {
15952                app.instrumentationUiAutomationConnection.shutdown();
15953            } catch (RemoteException re) {
15954                /* ignore */
15955            }
15956            // Only a UiAutomation can set this flag and now that
15957            // it is finished we make sure it is reset to its default.
15958            mUserIsMonkey = false;
15959        }
15960        app.instrumentationWatcher = null;
15961        app.instrumentationUiAutomationConnection = null;
15962        app.instrumentationClass = null;
15963        app.instrumentationInfo = null;
15964        app.instrumentationProfileFile = null;
15965        app.instrumentationArguments = null;
15966
15967        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15968                "finished inst");
15969    }
15970
15971    public void finishInstrumentation(IApplicationThread target,
15972            int resultCode, Bundle results) {
15973        int userId = UserHandle.getCallingUserId();
15974        // Refuse possible leaked file descriptors
15975        if (results != null && results.hasFileDescriptors()) {
15976            throw new IllegalArgumentException("File descriptors passed in Intent");
15977        }
15978
15979        synchronized(this) {
15980            ProcessRecord app = getRecordForAppLocked(target);
15981            if (app == null) {
15982                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15983                return;
15984            }
15985            final long origId = Binder.clearCallingIdentity();
15986            finishInstrumentationLocked(app, resultCode, results);
15987            Binder.restoreCallingIdentity(origId);
15988        }
15989    }
15990
15991    // =========================================================
15992    // CONFIGURATION
15993    // =========================================================
15994
15995    public ConfigurationInfo getDeviceConfigurationInfo() {
15996        ConfigurationInfo config = new ConfigurationInfo();
15997        synchronized (this) {
15998            config.reqTouchScreen = mConfiguration.touchscreen;
15999            config.reqKeyboardType = mConfiguration.keyboard;
16000            config.reqNavigation = mConfiguration.navigation;
16001            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16002                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16003                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16004            }
16005            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16006                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16007                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16008            }
16009            config.reqGlEsVersion = GL_ES_VERSION;
16010        }
16011        return config;
16012    }
16013
16014    ActivityStack getFocusedStack() {
16015        return mStackSupervisor.getFocusedStack();
16016    }
16017
16018    public Configuration getConfiguration() {
16019        Configuration ci;
16020        synchronized(this) {
16021            ci = new Configuration(mConfiguration);
16022        }
16023        return ci;
16024    }
16025
16026    public void updatePersistentConfiguration(Configuration values) {
16027        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16028                "updateConfiguration()");
16029        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16030                "updateConfiguration()");
16031        if (values == null) {
16032            throw new NullPointerException("Configuration must not be null");
16033        }
16034
16035        synchronized(this) {
16036            final long origId = Binder.clearCallingIdentity();
16037            updateConfigurationLocked(values, null, true, false);
16038            Binder.restoreCallingIdentity(origId);
16039        }
16040    }
16041
16042    public void updateConfiguration(Configuration values) {
16043        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16044                "updateConfiguration()");
16045
16046        synchronized(this) {
16047            if (values == null && mWindowManager != null) {
16048                // sentinel: fetch the current configuration from the window manager
16049                values = mWindowManager.computeNewConfiguration();
16050            }
16051
16052            if (mWindowManager != null) {
16053                mProcessList.applyDisplaySize(mWindowManager);
16054            }
16055
16056            final long origId = Binder.clearCallingIdentity();
16057            if (values != null) {
16058                Settings.System.clearConfiguration(values);
16059            }
16060            updateConfigurationLocked(values, null, false, false);
16061            Binder.restoreCallingIdentity(origId);
16062        }
16063    }
16064
16065    /**
16066     * Do either or both things: (1) change the current configuration, and (2)
16067     * make sure the given activity is running with the (now) current
16068     * configuration.  Returns true if the activity has been left running, or
16069     * false if <var>starting</var> is being destroyed to match the new
16070     * configuration.
16071     * @param persistent TODO
16072     */
16073    boolean updateConfigurationLocked(Configuration values,
16074            ActivityRecord starting, boolean persistent, boolean initLocale) {
16075        int changes = 0;
16076
16077        if (values != null) {
16078            Configuration newConfig = new Configuration(mConfiguration);
16079            changes = newConfig.updateFrom(values);
16080            if (changes != 0) {
16081                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16082                    Slog.i(TAG, "Updating configuration to: " + values);
16083                }
16084
16085                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16086
16087                if (values.locale != null && !initLocale) {
16088                    saveLocaleLocked(values.locale,
16089                                     !values.locale.equals(mConfiguration.locale),
16090                                     values.userSetLocale);
16091                }
16092
16093                mConfigurationSeq++;
16094                if (mConfigurationSeq <= 0) {
16095                    mConfigurationSeq = 1;
16096                }
16097                newConfig.seq = mConfigurationSeq;
16098                mConfiguration = newConfig;
16099                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16100                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16101                //mUsageStatsService.noteStartConfig(newConfig);
16102
16103                final Configuration configCopy = new Configuration(mConfiguration);
16104
16105                // TODO: If our config changes, should we auto dismiss any currently
16106                // showing dialogs?
16107                mShowDialogs = shouldShowDialogs(newConfig);
16108
16109                AttributeCache ac = AttributeCache.instance();
16110                if (ac != null) {
16111                    ac.updateConfiguration(configCopy);
16112                }
16113
16114                // Make sure all resources in our process are updated
16115                // right now, so that anyone who is going to retrieve
16116                // resource values after we return will be sure to get
16117                // the new ones.  This is especially important during
16118                // boot, where the first config change needs to guarantee
16119                // all resources have that config before following boot
16120                // code is executed.
16121                mSystemThread.applyConfigurationToResources(configCopy);
16122
16123                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16124                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16125                    msg.obj = new Configuration(configCopy);
16126                    mHandler.sendMessage(msg);
16127                }
16128
16129                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16130                    ProcessRecord app = mLruProcesses.get(i);
16131                    try {
16132                        if (app.thread != null) {
16133                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16134                                    + app.processName + " new config " + mConfiguration);
16135                            app.thread.scheduleConfigurationChanged(configCopy);
16136                        }
16137                    } catch (Exception e) {
16138                    }
16139                }
16140                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16141                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16142                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16143                        | Intent.FLAG_RECEIVER_FOREGROUND);
16144                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16145                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16146                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16147                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16148                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16149                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16150                    broadcastIntentLocked(null, null, intent,
16151                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16152                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16153                }
16154            }
16155        }
16156
16157        boolean kept = true;
16158        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16159        // mainStack is null during startup.
16160        if (mainStack != null) {
16161            if (changes != 0 && starting == null) {
16162                // If the configuration changed, and the caller is not already
16163                // in the process of starting an activity, then find the top
16164                // activity to check if its configuration needs to change.
16165                starting = mainStack.topRunningActivityLocked(null);
16166            }
16167
16168            if (starting != null) {
16169                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16170                // And we need to make sure at this point that all other activities
16171                // are made visible with the correct configuration.
16172                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16173            }
16174        }
16175
16176        if (values != null && mWindowManager != null) {
16177            mWindowManager.setNewConfiguration(mConfiguration);
16178        }
16179
16180        return kept;
16181    }
16182
16183    /**
16184     * Decide based on the configuration whether we should shouw the ANR,
16185     * crash, etc dialogs.  The idea is that if there is no affordnace to
16186     * press the on-screen buttons, we shouldn't show the dialog.
16187     *
16188     * A thought: SystemUI might also want to get told about this, the Power
16189     * dialog / global actions also might want different behaviors.
16190     */
16191    private static final boolean shouldShowDialogs(Configuration config) {
16192        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16193                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16194    }
16195
16196    /**
16197     * Save the locale.  You must be inside a synchronized (this) block.
16198     */
16199    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16200        if(isDiff) {
16201            SystemProperties.set("user.language", l.getLanguage());
16202            SystemProperties.set("user.region", l.getCountry());
16203        }
16204
16205        if(isPersist) {
16206            SystemProperties.set("persist.sys.language", l.getLanguage());
16207            SystemProperties.set("persist.sys.country", l.getCountry());
16208            SystemProperties.set("persist.sys.localevar", l.getVariant());
16209        }
16210    }
16211
16212    @Override
16213    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16214        synchronized (this) {
16215            ActivityRecord srec = ActivityRecord.forToken(token);
16216            if (srec.task != null && srec.task.stack != null) {
16217                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16218            }
16219        }
16220        return false;
16221    }
16222
16223    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16224            Intent resultData) {
16225
16226        synchronized (this) {
16227            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16228            if (stack != null) {
16229                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16230            }
16231            return false;
16232        }
16233    }
16234
16235    public int getLaunchedFromUid(IBinder activityToken) {
16236        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16237        if (srec == null) {
16238            return -1;
16239        }
16240        return srec.launchedFromUid;
16241    }
16242
16243    public String getLaunchedFromPackage(IBinder activityToken) {
16244        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16245        if (srec == null) {
16246            return null;
16247        }
16248        return srec.launchedFromPackage;
16249    }
16250
16251    // =========================================================
16252    // LIFETIME MANAGEMENT
16253    // =========================================================
16254
16255    // Returns which broadcast queue the app is the current [or imminent] receiver
16256    // on, or 'null' if the app is not an active broadcast recipient.
16257    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16258        BroadcastRecord r = app.curReceiver;
16259        if (r != null) {
16260            return r.queue;
16261        }
16262
16263        // It's not the current receiver, but it might be starting up to become one
16264        synchronized (this) {
16265            for (BroadcastQueue queue : mBroadcastQueues) {
16266                r = queue.mPendingBroadcast;
16267                if (r != null && r.curApp == app) {
16268                    // found it; report which queue it's in
16269                    return queue;
16270                }
16271            }
16272        }
16273
16274        return null;
16275    }
16276
16277    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16278            boolean doingAll, long now) {
16279        if (mAdjSeq == app.adjSeq) {
16280            // This adjustment has already been computed.
16281            return app.curRawAdj;
16282        }
16283
16284        if (app.thread == null) {
16285            app.adjSeq = mAdjSeq;
16286            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16287            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16288            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16289        }
16290
16291        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16292        app.adjSource = null;
16293        app.adjTarget = null;
16294        app.empty = false;
16295        app.cached = false;
16296
16297        final int activitiesSize = app.activities.size();
16298
16299        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16300            // The max adjustment doesn't allow this app to be anything
16301            // below foreground, so it is not worth doing work for it.
16302            app.adjType = "fixed";
16303            app.adjSeq = mAdjSeq;
16304            app.curRawAdj = app.maxAdj;
16305            app.foregroundActivities = false;
16306            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16307            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16308            // System processes can do UI, and when they do we want to have
16309            // them trim their memory after the user leaves the UI.  To
16310            // facilitate this, here we need to determine whether or not it
16311            // is currently showing UI.
16312            app.systemNoUi = true;
16313            if (app == TOP_APP) {
16314                app.systemNoUi = false;
16315            } else if (activitiesSize > 0) {
16316                for (int j = 0; j < activitiesSize; j++) {
16317                    final ActivityRecord r = app.activities.get(j);
16318                    if (r.visible) {
16319                        app.systemNoUi = false;
16320                    }
16321                }
16322            }
16323            if (!app.systemNoUi) {
16324                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16325            }
16326            return (app.curAdj=app.maxAdj);
16327        }
16328
16329        app.systemNoUi = false;
16330
16331        // Determine the importance of the process, starting with most
16332        // important to least, and assign an appropriate OOM adjustment.
16333        int adj;
16334        int schedGroup;
16335        int procState;
16336        boolean foregroundActivities = false;
16337        BroadcastQueue queue;
16338        if (app == TOP_APP) {
16339            // The last app on the list is the foreground app.
16340            adj = ProcessList.FOREGROUND_APP_ADJ;
16341            schedGroup = Process.THREAD_GROUP_DEFAULT;
16342            app.adjType = "top-activity";
16343            foregroundActivities = true;
16344            procState = ActivityManager.PROCESS_STATE_TOP;
16345        } else if (app.instrumentationClass != null) {
16346            // Don't want to kill running instrumentation.
16347            adj = ProcessList.FOREGROUND_APP_ADJ;
16348            schedGroup = Process.THREAD_GROUP_DEFAULT;
16349            app.adjType = "instrumentation";
16350            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16351        } else if ((queue = isReceivingBroadcast(app)) != null) {
16352            // An app that is currently receiving a broadcast also
16353            // counts as being in the foreground for OOM killer purposes.
16354            // It's placed in a sched group based on the nature of the
16355            // broadcast as reflected by which queue it's active in.
16356            adj = ProcessList.FOREGROUND_APP_ADJ;
16357            schedGroup = (queue == mFgBroadcastQueue)
16358                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16359            app.adjType = "broadcast";
16360            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16361        } else if (app.executingServices.size() > 0) {
16362            // An app that is currently executing a service callback also
16363            // counts as being in the foreground.
16364            adj = ProcessList.FOREGROUND_APP_ADJ;
16365            schedGroup = app.execServicesFg ?
16366                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16367            app.adjType = "exec-service";
16368            procState = ActivityManager.PROCESS_STATE_SERVICE;
16369            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16370        } else {
16371            // As far as we know the process is empty.  We may change our mind later.
16372            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16373            // At this point we don't actually know the adjustment.  Use the cached adj
16374            // value that the caller wants us to.
16375            adj = cachedAdj;
16376            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16377            app.cached = true;
16378            app.empty = true;
16379            app.adjType = "cch-empty";
16380        }
16381
16382        // Examine all activities if not already foreground.
16383        if (!foregroundActivities && activitiesSize > 0) {
16384            for (int j = 0; j < activitiesSize; j++) {
16385                final ActivityRecord r = app.activities.get(j);
16386                if (r.app != app) {
16387                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16388                            + app + "?!?");
16389                    continue;
16390                }
16391                if (r.visible) {
16392                    // App has a visible activity; only upgrade adjustment.
16393                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16394                        adj = ProcessList.VISIBLE_APP_ADJ;
16395                        app.adjType = "visible";
16396                    }
16397                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16398                        procState = ActivityManager.PROCESS_STATE_TOP;
16399                    }
16400                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16401                    app.cached = false;
16402                    app.empty = false;
16403                    foregroundActivities = true;
16404                    break;
16405                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16406                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16407                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16408                        app.adjType = "pausing";
16409                    }
16410                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16411                        procState = ActivityManager.PROCESS_STATE_TOP;
16412                    }
16413                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16414                    app.cached = false;
16415                    app.empty = false;
16416                    foregroundActivities = true;
16417                } else if (r.state == ActivityState.STOPPING) {
16418                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16419                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16420                        app.adjType = "stopping";
16421                    }
16422                    // For the process state, we will at this point consider the
16423                    // process to be cached.  It will be cached either as an activity
16424                    // or empty depending on whether the activity is finishing.  We do
16425                    // this so that we can treat the process as cached for purposes of
16426                    // memory trimming (determing current memory level, trim command to
16427                    // send to process) since there can be an arbitrary number of stopping
16428                    // processes and they should soon all go into the cached state.
16429                    if (!r.finishing) {
16430                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16431                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16432                        }
16433                    }
16434                    app.cached = false;
16435                    app.empty = false;
16436                    foregroundActivities = true;
16437                } else {
16438                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16439                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16440                        app.adjType = "cch-act";
16441                    }
16442                }
16443            }
16444        }
16445
16446        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16447            if (app.foregroundServices) {
16448                // The user is aware of this app, so make it visible.
16449                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16450                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16451                app.cached = false;
16452                app.adjType = "fg-service";
16453                schedGroup = Process.THREAD_GROUP_DEFAULT;
16454            } else if (app.forcingToForeground != null) {
16455                // The user is aware of this app, so make it visible.
16456                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16457                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16458                app.cached = false;
16459                app.adjType = "force-fg";
16460                app.adjSource = app.forcingToForeground;
16461                schedGroup = Process.THREAD_GROUP_DEFAULT;
16462            }
16463        }
16464
16465        if (app == mHeavyWeightProcess) {
16466            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16467                // We don't want to kill the current heavy-weight process.
16468                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16469                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16470                app.cached = false;
16471                app.adjType = "heavy";
16472            }
16473            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16474                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16475            }
16476        }
16477
16478        if (app == mHomeProcess) {
16479            if (adj > ProcessList.HOME_APP_ADJ) {
16480                // This process is hosting what we currently consider to be the
16481                // home app, so we don't want to let it go into the background.
16482                adj = ProcessList.HOME_APP_ADJ;
16483                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16484                app.cached = false;
16485                app.adjType = "home";
16486            }
16487            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16488                procState = ActivityManager.PROCESS_STATE_HOME;
16489            }
16490        }
16491
16492        if (app == mPreviousProcess && app.activities.size() > 0) {
16493            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16494                // This was the previous process that showed UI to the user.
16495                // We want to try to keep it around more aggressively, to give
16496                // a good experience around switching between two apps.
16497                adj = ProcessList.PREVIOUS_APP_ADJ;
16498                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16499                app.cached = false;
16500                app.adjType = "previous";
16501            }
16502            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16503                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16504            }
16505        }
16506
16507        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16508                + " reason=" + app.adjType);
16509
16510        // By default, we use the computed adjustment.  It may be changed if
16511        // there are applications dependent on our services or providers, but
16512        // this gives us a baseline and makes sure we don't get into an
16513        // infinite recursion.
16514        app.adjSeq = mAdjSeq;
16515        app.curRawAdj = adj;
16516        app.hasStartedServices = false;
16517
16518        if (mBackupTarget != null && app == mBackupTarget.app) {
16519            // If possible we want to avoid killing apps while they're being backed up
16520            if (adj > ProcessList.BACKUP_APP_ADJ) {
16521                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16522                adj = ProcessList.BACKUP_APP_ADJ;
16523                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16524                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16525                }
16526                app.adjType = "backup";
16527                app.cached = false;
16528            }
16529            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16530                procState = ActivityManager.PROCESS_STATE_BACKUP;
16531            }
16532        }
16533
16534        boolean mayBeTop = false;
16535
16536        for (int is = app.services.size()-1;
16537                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16538                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16539                        || procState > ActivityManager.PROCESS_STATE_TOP);
16540                is--) {
16541            ServiceRecord s = app.services.valueAt(is);
16542            if (s.startRequested) {
16543                app.hasStartedServices = true;
16544                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16545                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16546                }
16547                if (app.hasShownUi && app != mHomeProcess) {
16548                    // If this process has shown some UI, let it immediately
16549                    // go to the LRU list because it may be pretty heavy with
16550                    // UI stuff.  We'll tag it with a label just to help
16551                    // debug and understand what is going on.
16552                    if (adj > ProcessList.SERVICE_ADJ) {
16553                        app.adjType = "cch-started-ui-services";
16554                    }
16555                } else {
16556                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16557                        // This service has seen some activity within
16558                        // recent memory, so we will keep its process ahead
16559                        // of the background processes.
16560                        if (adj > ProcessList.SERVICE_ADJ) {
16561                            adj = ProcessList.SERVICE_ADJ;
16562                            app.adjType = "started-services";
16563                            app.cached = false;
16564                        }
16565                    }
16566                    // If we have let the service slide into the background
16567                    // state, still have some text describing what it is doing
16568                    // even though the service no longer has an impact.
16569                    if (adj > ProcessList.SERVICE_ADJ) {
16570                        app.adjType = "cch-started-services";
16571                    }
16572                }
16573            }
16574            for (int conni = s.connections.size()-1;
16575                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16576                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16577                            || procState > ActivityManager.PROCESS_STATE_TOP);
16578                    conni--) {
16579                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16580                for (int i = 0;
16581                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16582                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16583                                || procState > ActivityManager.PROCESS_STATE_TOP);
16584                        i++) {
16585                    // XXX should compute this based on the max of
16586                    // all connected clients.
16587                    ConnectionRecord cr = clist.get(i);
16588                    if (cr.binding.client == app) {
16589                        // Binding to ourself is not interesting.
16590                        continue;
16591                    }
16592                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16593                        ProcessRecord client = cr.binding.client;
16594                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16595                                TOP_APP, doingAll, now);
16596                        int clientProcState = client.curProcState;
16597                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16598                            // If the other app is cached for any reason, for purposes here
16599                            // we are going to consider it empty.  The specific cached state
16600                            // doesn't propagate except under certain conditions.
16601                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16602                        }
16603                        String adjType = null;
16604                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16605                            // Not doing bind OOM management, so treat
16606                            // this guy more like a started service.
16607                            if (app.hasShownUi && app != mHomeProcess) {
16608                                // If this process has shown some UI, let it immediately
16609                                // go to the LRU list because it may be pretty heavy with
16610                                // UI stuff.  We'll tag it with a label just to help
16611                                // debug and understand what is going on.
16612                                if (adj > clientAdj) {
16613                                    adjType = "cch-bound-ui-services";
16614                                }
16615                                app.cached = false;
16616                                clientAdj = adj;
16617                                clientProcState = procState;
16618                            } else {
16619                                if (now >= (s.lastActivity
16620                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16621                                    // This service has not seen activity within
16622                                    // recent memory, so allow it to drop to the
16623                                    // LRU list if there is no other reason to keep
16624                                    // it around.  We'll also tag it with a label just
16625                                    // to help debug and undertand what is going on.
16626                                    if (adj > clientAdj) {
16627                                        adjType = "cch-bound-services";
16628                                    }
16629                                    clientAdj = adj;
16630                                }
16631                            }
16632                        }
16633                        if (adj > clientAdj) {
16634                            // If this process has recently shown UI, and
16635                            // the process that is binding to it is less
16636                            // important than being visible, then we don't
16637                            // care about the binding as much as we care
16638                            // about letting this process get into the LRU
16639                            // list to be killed and restarted if needed for
16640                            // memory.
16641                            if (app.hasShownUi && app != mHomeProcess
16642                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16643                                adjType = "cch-bound-ui-services";
16644                            } else {
16645                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16646                                        |Context.BIND_IMPORTANT)) != 0) {
16647                                    adj = clientAdj;
16648                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16649                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16650                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16651                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16652                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16653                                    adj = clientAdj;
16654                                } else {
16655                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16656                                        adj = ProcessList.VISIBLE_APP_ADJ;
16657                                    }
16658                                }
16659                                if (!client.cached) {
16660                                    app.cached = false;
16661                                }
16662                                adjType = "service";
16663                            }
16664                        }
16665                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16666                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16667                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16668                            }
16669                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16670                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16671                                    // Special handling of clients who are in the top state.
16672                                    // We *may* want to consider this process to be in the
16673                                    // top state as well, but only if there is not another
16674                                    // reason for it to be running.  Being on the top is a
16675                                    // special state, meaning you are specifically running
16676                                    // for the current top app.  If the process is already
16677                                    // running in the background for some other reason, it
16678                                    // is more important to continue considering it to be
16679                                    // in the background state.
16680                                    mayBeTop = true;
16681                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16682                                } else {
16683                                    // Special handling for above-top states (persistent
16684                                    // processes).  These should not bring the current process
16685                                    // into the top state, since they are not on top.  Instead
16686                                    // give them the best state after that.
16687                                    clientProcState =
16688                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16689                                }
16690                            }
16691                        } else {
16692                            if (clientProcState <
16693                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16694                                clientProcState =
16695                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16696                            }
16697                        }
16698                        if (procState > clientProcState) {
16699                            procState = clientProcState;
16700                        }
16701                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16702                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16703                            app.pendingUiClean = true;
16704                        }
16705                        if (adjType != null) {
16706                            app.adjType = adjType;
16707                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16708                                    .REASON_SERVICE_IN_USE;
16709                            app.adjSource = cr.binding.client;
16710                            app.adjSourceProcState = clientProcState;
16711                            app.adjTarget = s.name;
16712                        }
16713                    }
16714                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16715                        app.treatLikeActivity = true;
16716                    }
16717                    final ActivityRecord a = cr.activity;
16718                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16719                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16720                                (a.visible || a.state == ActivityState.RESUMED
16721                                 || a.state == ActivityState.PAUSING)) {
16722                            adj = ProcessList.FOREGROUND_APP_ADJ;
16723                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16724                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16725                            }
16726                            app.cached = false;
16727                            app.adjType = "service";
16728                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16729                                    .REASON_SERVICE_IN_USE;
16730                            app.adjSource = a;
16731                            app.adjSourceProcState = procState;
16732                            app.adjTarget = s.name;
16733                        }
16734                    }
16735                }
16736            }
16737        }
16738
16739        for (int provi = app.pubProviders.size()-1;
16740                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16741                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16742                        || procState > ActivityManager.PROCESS_STATE_TOP);
16743                provi--) {
16744            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16745            for (int i = cpr.connections.size()-1;
16746                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16747                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16748                            || procState > ActivityManager.PROCESS_STATE_TOP);
16749                    i--) {
16750                ContentProviderConnection conn = cpr.connections.get(i);
16751                ProcessRecord client = conn.client;
16752                if (client == app) {
16753                    // Being our own client is not interesting.
16754                    continue;
16755                }
16756                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16757                int clientProcState = client.curProcState;
16758                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16759                    // If the other app is cached for any reason, for purposes here
16760                    // we are going to consider it empty.
16761                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16762                }
16763                if (adj > clientAdj) {
16764                    if (app.hasShownUi && app != mHomeProcess
16765                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16766                        app.adjType = "cch-ui-provider";
16767                    } else {
16768                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16769                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16770                        app.adjType = "provider";
16771                    }
16772                    app.cached &= client.cached;
16773                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16774                            .REASON_PROVIDER_IN_USE;
16775                    app.adjSource = client;
16776                    app.adjSourceProcState = clientProcState;
16777                    app.adjTarget = cpr.name;
16778                }
16779                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16780                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16781                        // Special handling of clients who are in the top state.
16782                        // We *may* want to consider this process to be in the
16783                        // top state as well, but only if there is not another
16784                        // reason for it to be running.  Being on the top is a
16785                        // special state, meaning you are specifically running
16786                        // for the current top app.  If the process is already
16787                        // running in the background for some other reason, it
16788                        // is more important to continue considering it to be
16789                        // in the background state.
16790                        mayBeTop = true;
16791                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16792                    } else {
16793                        // Special handling for above-top states (persistent
16794                        // processes).  These should not bring the current process
16795                        // into the top state, since they are not on top.  Instead
16796                        // give them the best state after that.
16797                        clientProcState =
16798                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16799                    }
16800                }
16801                if (procState > clientProcState) {
16802                    procState = clientProcState;
16803                }
16804                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16805                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16806                }
16807            }
16808            // If the provider has external (non-framework) process
16809            // dependencies, ensure that its adjustment is at least
16810            // FOREGROUND_APP_ADJ.
16811            if (cpr.hasExternalProcessHandles()) {
16812                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16813                    adj = ProcessList.FOREGROUND_APP_ADJ;
16814                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16815                    app.cached = false;
16816                    app.adjType = "provider";
16817                    app.adjTarget = cpr.name;
16818                }
16819                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16820                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16821                }
16822            }
16823        }
16824
16825        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16826            // A client of one of our services or providers is in the top state.  We
16827            // *may* want to be in the top state, but not if we are already running in
16828            // the background for some other reason.  For the decision here, we are going
16829            // to pick out a few specific states that we want to remain in when a client
16830            // is top (states that tend to be longer-term) and otherwise allow it to go
16831            // to the top state.
16832            switch (procState) {
16833                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16834                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16835                case ActivityManager.PROCESS_STATE_SERVICE:
16836                    // These all are longer-term states, so pull them up to the top
16837                    // of the background states, but not all the way to the top state.
16838                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16839                    break;
16840                default:
16841                    // Otherwise, top is a better choice, so take it.
16842                    procState = ActivityManager.PROCESS_STATE_TOP;
16843                    break;
16844            }
16845        }
16846
16847        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16848            if (app.hasClientActivities) {
16849                // This is a cached process, but with client activities.  Mark it so.
16850                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16851                app.adjType = "cch-client-act";
16852            } else if (app.treatLikeActivity) {
16853                // This is a cached process, but somebody wants us to treat it like it has
16854                // an activity, okay!
16855                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16856                app.adjType = "cch-as-act";
16857            }
16858        }
16859
16860        if (adj == ProcessList.SERVICE_ADJ) {
16861            if (doingAll) {
16862                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16863                mNewNumServiceProcs++;
16864                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16865                if (!app.serviceb) {
16866                    // This service isn't far enough down on the LRU list to
16867                    // normally be a B service, but if we are low on RAM and it
16868                    // is large we want to force it down since we would prefer to
16869                    // keep launcher over it.
16870                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16871                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16872                        app.serviceHighRam = true;
16873                        app.serviceb = true;
16874                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16875                    } else {
16876                        mNewNumAServiceProcs++;
16877                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16878                    }
16879                } else {
16880                    app.serviceHighRam = false;
16881                }
16882            }
16883            if (app.serviceb) {
16884                adj = ProcessList.SERVICE_B_ADJ;
16885            }
16886        }
16887
16888        app.curRawAdj = adj;
16889
16890        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16891        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16892        if (adj > app.maxAdj) {
16893            adj = app.maxAdj;
16894            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16895                schedGroup = Process.THREAD_GROUP_DEFAULT;
16896            }
16897        }
16898
16899        // Do final modification to adj.  Everything we do between here and applying
16900        // the final setAdj must be done in this function, because we will also use
16901        // it when computing the final cached adj later.  Note that we don't need to
16902        // worry about this for max adj above, since max adj will always be used to
16903        // keep it out of the cached vaues.
16904        app.curAdj = app.modifyRawOomAdj(adj);
16905        app.curSchedGroup = schedGroup;
16906        app.curProcState = procState;
16907        app.foregroundActivities = foregroundActivities;
16908
16909        return app.curRawAdj;
16910    }
16911
16912    /**
16913     * Schedule PSS collection of a process.
16914     */
16915    void requestPssLocked(ProcessRecord proc, int procState) {
16916        if (mPendingPssProcesses.contains(proc)) {
16917            return;
16918        }
16919        if (mPendingPssProcesses.size() == 0) {
16920            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16921        }
16922        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16923        proc.pssProcState = procState;
16924        mPendingPssProcesses.add(proc);
16925    }
16926
16927    /**
16928     * Schedule PSS collection of all processes.
16929     */
16930    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16931        if (!always) {
16932            if (now < (mLastFullPssTime +
16933                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16934                return;
16935            }
16936        }
16937        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16938        mLastFullPssTime = now;
16939        mFullPssPending = true;
16940        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16941        mPendingPssProcesses.clear();
16942        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16943            ProcessRecord app = mLruProcesses.get(i);
16944            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16945                app.pssProcState = app.setProcState;
16946                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16947                        isSleeping(), now);
16948                mPendingPssProcesses.add(app);
16949            }
16950        }
16951        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16952    }
16953
16954    /**
16955     * Ask a given process to GC right now.
16956     */
16957    final void performAppGcLocked(ProcessRecord app) {
16958        try {
16959            app.lastRequestedGc = SystemClock.uptimeMillis();
16960            if (app.thread != null) {
16961                if (app.reportLowMemory) {
16962                    app.reportLowMemory = false;
16963                    app.thread.scheduleLowMemory();
16964                } else {
16965                    app.thread.processInBackground();
16966                }
16967            }
16968        } catch (Exception e) {
16969            // whatever.
16970        }
16971    }
16972
16973    /**
16974     * Returns true if things are idle enough to perform GCs.
16975     */
16976    private final boolean canGcNowLocked() {
16977        boolean processingBroadcasts = false;
16978        for (BroadcastQueue q : mBroadcastQueues) {
16979            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16980                processingBroadcasts = true;
16981            }
16982        }
16983        return !processingBroadcasts
16984                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16985    }
16986
16987    /**
16988     * Perform GCs on all processes that are waiting for it, but only
16989     * if things are idle.
16990     */
16991    final void performAppGcsLocked() {
16992        final int N = mProcessesToGc.size();
16993        if (N <= 0) {
16994            return;
16995        }
16996        if (canGcNowLocked()) {
16997            while (mProcessesToGc.size() > 0) {
16998                ProcessRecord proc = mProcessesToGc.remove(0);
16999                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17000                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17001                            <= SystemClock.uptimeMillis()) {
17002                        // To avoid spamming the system, we will GC processes one
17003                        // at a time, waiting a few seconds between each.
17004                        performAppGcLocked(proc);
17005                        scheduleAppGcsLocked();
17006                        return;
17007                    } else {
17008                        // It hasn't been long enough since we last GCed this
17009                        // process...  put it in the list to wait for its time.
17010                        addProcessToGcListLocked(proc);
17011                        break;
17012                    }
17013                }
17014            }
17015
17016            scheduleAppGcsLocked();
17017        }
17018    }
17019
17020    /**
17021     * If all looks good, perform GCs on all processes waiting for them.
17022     */
17023    final void performAppGcsIfAppropriateLocked() {
17024        if (canGcNowLocked()) {
17025            performAppGcsLocked();
17026            return;
17027        }
17028        // Still not idle, wait some more.
17029        scheduleAppGcsLocked();
17030    }
17031
17032    /**
17033     * Schedule the execution of all pending app GCs.
17034     */
17035    final void scheduleAppGcsLocked() {
17036        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17037
17038        if (mProcessesToGc.size() > 0) {
17039            // Schedule a GC for the time to the next process.
17040            ProcessRecord proc = mProcessesToGc.get(0);
17041            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17042
17043            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17044            long now = SystemClock.uptimeMillis();
17045            if (when < (now+GC_TIMEOUT)) {
17046                when = now + GC_TIMEOUT;
17047            }
17048            mHandler.sendMessageAtTime(msg, when);
17049        }
17050    }
17051
17052    /**
17053     * Add a process to the array of processes waiting to be GCed.  Keeps the
17054     * list in sorted order by the last GC time.  The process can't already be
17055     * on the list.
17056     */
17057    final void addProcessToGcListLocked(ProcessRecord proc) {
17058        boolean added = false;
17059        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17060            if (mProcessesToGc.get(i).lastRequestedGc <
17061                    proc.lastRequestedGc) {
17062                added = true;
17063                mProcessesToGc.add(i+1, proc);
17064                break;
17065            }
17066        }
17067        if (!added) {
17068            mProcessesToGc.add(0, proc);
17069        }
17070    }
17071
17072    /**
17073     * Set up to ask a process to GC itself.  This will either do it
17074     * immediately, or put it on the list of processes to gc the next
17075     * time things are idle.
17076     */
17077    final void scheduleAppGcLocked(ProcessRecord app) {
17078        long now = SystemClock.uptimeMillis();
17079        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17080            return;
17081        }
17082        if (!mProcessesToGc.contains(app)) {
17083            addProcessToGcListLocked(app);
17084            scheduleAppGcsLocked();
17085        }
17086    }
17087
17088    final void checkExcessivePowerUsageLocked(boolean doKills) {
17089        updateCpuStatsNow();
17090
17091        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17092        boolean doWakeKills = doKills;
17093        boolean doCpuKills = doKills;
17094        if (mLastPowerCheckRealtime == 0) {
17095            doWakeKills = false;
17096        }
17097        if (mLastPowerCheckUptime == 0) {
17098            doCpuKills = false;
17099        }
17100        if (stats.isScreenOn()) {
17101            doWakeKills = false;
17102        }
17103        final long curRealtime = SystemClock.elapsedRealtime();
17104        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17105        final long curUptime = SystemClock.uptimeMillis();
17106        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17107        mLastPowerCheckRealtime = curRealtime;
17108        mLastPowerCheckUptime = curUptime;
17109        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17110            doWakeKills = false;
17111        }
17112        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17113            doCpuKills = false;
17114        }
17115        int i = mLruProcesses.size();
17116        while (i > 0) {
17117            i--;
17118            ProcessRecord app = mLruProcesses.get(i);
17119            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17120                long wtime;
17121                synchronized (stats) {
17122                    wtime = stats.getProcessWakeTime(app.info.uid,
17123                            app.pid, curRealtime);
17124                }
17125                long wtimeUsed = wtime - app.lastWakeTime;
17126                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17127                if (DEBUG_POWER) {
17128                    StringBuilder sb = new StringBuilder(128);
17129                    sb.append("Wake for ");
17130                    app.toShortString(sb);
17131                    sb.append(": over ");
17132                    TimeUtils.formatDuration(realtimeSince, sb);
17133                    sb.append(" used ");
17134                    TimeUtils.formatDuration(wtimeUsed, sb);
17135                    sb.append(" (");
17136                    sb.append((wtimeUsed*100)/realtimeSince);
17137                    sb.append("%)");
17138                    Slog.i(TAG, sb.toString());
17139                    sb.setLength(0);
17140                    sb.append("CPU for ");
17141                    app.toShortString(sb);
17142                    sb.append(": over ");
17143                    TimeUtils.formatDuration(uptimeSince, sb);
17144                    sb.append(" used ");
17145                    TimeUtils.formatDuration(cputimeUsed, sb);
17146                    sb.append(" (");
17147                    sb.append((cputimeUsed*100)/uptimeSince);
17148                    sb.append("%)");
17149                    Slog.i(TAG, sb.toString());
17150                }
17151                // If a process has held a wake lock for more
17152                // than 50% of the time during this period,
17153                // that sounds bad.  Kill!
17154                if (doWakeKills && realtimeSince > 0
17155                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17156                    synchronized (stats) {
17157                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17158                                realtimeSince, wtimeUsed);
17159                    }
17160                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17161                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17162                } else if (doCpuKills && uptimeSince > 0
17163                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17164                    synchronized (stats) {
17165                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17166                                uptimeSince, cputimeUsed);
17167                    }
17168                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17169                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17170                } else {
17171                    app.lastWakeTime = wtime;
17172                    app.lastCpuTime = app.curCpuTime;
17173                }
17174            }
17175        }
17176    }
17177
17178    private final boolean applyOomAdjLocked(ProcessRecord app,
17179            ProcessRecord TOP_APP, boolean doingAll, long now) {
17180        boolean success = true;
17181
17182        if (app.curRawAdj != app.setRawAdj) {
17183            app.setRawAdj = app.curRawAdj;
17184        }
17185
17186        int changes = 0;
17187
17188        if (app.curAdj != app.setAdj) {
17189            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17190            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17191                TAG, "Set " + app.pid + " " + app.processName +
17192                " adj " + app.curAdj + ": " + app.adjType);
17193            app.setAdj = app.curAdj;
17194        }
17195
17196        if (app.setSchedGroup != app.curSchedGroup) {
17197            app.setSchedGroup = app.curSchedGroup;
17198            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17199                    "Setting process group of " + app.processName
17200                    + " to " + app.curSchedGroup);
17201            if (app.waitingToKill != null &&
17202                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17203                app.kill(app.waitingToKill, true);
17204                success = false;
17205            } else {
17206                if (true) {
17207                    long oldId = Binder.clearCallingIdentity();
17208                    try {
17209                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17210                    } catch (Exception e) {
17211                        Slog.w(TAG, "Failed setting process group of " + app.pid
17212                                + " to " + app.curSchedGroup);
17213                        e.printStackTrace();
17214                    } finally {
17215                        Binder.restoreCallingIdentity(oldId);
17216                    }
17217                } else {
17218                    if (app.thread != null) {
17219                        try {
17220                            app.thread.setSchedulingGroup(app.curSchedGroup);
17221                        } catch (RemoteException e) {
17222                        }
17223                    }
17224                }
17225                Process.setSwappiness(app.pid,
17226                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17227            }
17228        }
17229        if (app.repForegroundActivities != app.foregroundActivities) {
17230            app.repForegroundActivities = app.foregroundActivities;
17231            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17232        }
17233        if (app.repProcState != app.curProcState) {
17234            app.repProcState = app.curProcState;
17235            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17236            if (app.thread != null) {
17237                try {
17238                    if (false) {
17239                        //RuntimeException h = new RuntimeException("here");
17240                        Slog.i(TAG, "Sending new process state " + app.repProcState
17241                                + " to " + app /*, h*/);
17242                    }
17243                    app.thread.setProcessState(app.repProcState);
17244                } catch (RemoteException e) {
17245                }
17246            }
17247        }
17248        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17249                app.setProcState)) {
17250            app.lastStateTime = now;
17251            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17252                    isSleeping(), now);
17253            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17254                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17255                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17256                    + (app.nextPssTime-now) + ": " + app);
17257        } else {
17258            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17259                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17260                requestPssLocked(app, app.setProcState);
17261                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17262                        isSleeping(), now);
17263            } else if (false && DEBUG_PSS) {
17264                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17265            }
17266        }
17267        if (app.setProcState != app.curProcState) {
17268            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17269                    "Proc state change of " + app.processName
17270                    + " to " + app.curProcState);
17271            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17272            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17273            if (setImportant && !curImportant) {
17274                // This app is no longer something we consider important enough to allow to
17275                // use arbitrary amounts of battery power.  Note
17276                // its current wake lock time to later know to kill it if
17277                // it is not behaving well.
17278                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17279                synchronized (stats) {
17280                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17281                            app.pid, SystemClock.elapsedRealtime());
17282                }
17283                app.lastCpuTime = app.curCpuTime;
17284
17285            }
17286            app.setProcState = app.curProcState;
17287            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17288                app.notCachedSinceIdle = false;
17289            }
17290            if (!doingAll) {
17291                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17292            } else {
17293                app.procStateChanged = true;
17294            }
17295        }
17296
17297        if (changes != 0) {
17298            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17299            int i = mPendingProcessChanges.size()-1;
17300            ProcessChangeItem item = null;
17301            while (i >= 0) {
17302                item = mPendingProcessChanges.get(i);
17303                if (item.pid == app.pid) {
17304                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17305                    break;
17306                }
17307                i--;
17308            }
17309            if (i < 0) {
17310                // No existing item in pending changes; need a new one.
17311                final int NA = mAvailProcessChanges.size();
17312                if (NA > 0) {
17313                    item = mAvailProcessChanges.remove(NA-1);
17314                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17315                } else {
17316                    item = new ProcessChangeItem();
17317                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17318                }
17319                item.changes = 0;
17320                item.pid = app.pid;
17321                item.uid = app.info.uid;
17322                if (mPendingProcessChanges.size() == 0) {
17323                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17324                            "*** Enqueueing dispatch processes changed!");
17325                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17326                }
17327                mPendingProcessChanges.add(item);
17328            }
17329            item.changes |= changes;
17330            item.processState = app.repProcState;
17331            item.foregroundActivities = app.repForegroundActivities;
17332            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17333                    + Integer.toHexString(System.identityHashCode(item))
17334                    + " " + app.toShortString() + ": changes=" + item.changes
17335                    + " procState=" + item.processState
17336                    + " foreground=" + item.foregroundActivities
17337                    + " type=" + app.adjType + " source=" + app.adjSource
17338                    + " target=" + app.adjTarget);
17339        }
17340
17341        return success;
17342    }
17343
17344    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17345        if (proc.thread != null) {
17346            if (proc.baseProcessTracker != null) {
17347                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17348            }
17349            if (proc.repProcState >= 0) {
17350                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17351                        proc.repProcState);
17352            }
17353        }
17354    }
17355
17356    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17357            ProcessRecord TOP_APP, boolean doingAll, long now) {
17358        if (app.thread == null) {
17359            return false;
17360        }
17361
17362        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17363
17364        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17365    }
17366
17367    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17368            boolean oomAdj) {
17369        if (isForeground != proc.foregroundServices) {
17370            proc.foregroundServices = isForeground;
17371            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17372                    proc.info.uid);
17373            if (isForeground) {
17374                if (curProcs == null) {
17375                    curProcs = new ArrayList<ProcessRecord>();
17376                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17377                }
17378                if (!curProcs.contains(proc)) {
17379                    curProcs.add(proc);
17380                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17381                            proc.info.packageName, proc.info.uid);
17382                }
17383            } else {
17384                if (curProcs != null) {
17385                    if (curProcs.remove(proc)) {
17386                        mBatteryStatsService.noteEvent(
17387                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17388                                proc.info.packageName, proc.info.uid);
17389                        if (curProcs.size() <= 0) {
17390                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17391                        }
17392                    }
17393                }
17394            }
17395            if (oomAdj) {
17396                updateOomAdjLocked();
17397            }
17398        }
17399    }
17400
17401    private final ActivityRecord resumedAppLocked() {
17402        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17403        String pkg;
17404        int uid;
17405        if (act != null) {
17406            pkg = act.packageName;
17407            uid = act.info.applicationInfo.uid;
17408        } else {
17409            pkg = null;
17410            uid = -1;
17411        }
17412        // Has the UID or resumed package name changed?
17413        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17414                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17415            if (mCurResumedPackage != null) {
17416                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17417                        mCurResumedPackage, mCurResumedUid);
17418            }
17419            mCurResumedPackage = pkg;
17420            mCurResumedUid = uid;
17421            if (mCurResumedPackage != null) {
17422                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17423                        mCurResumedPackage, mCurResumedUid);
17424            }
17425        }
17426        return act;
17427    }
17428
17429    final boolean updateOomAdjLocked(ProcessRecord app) {
17430        final ActivityRecord TOP_ACT = resumedAppLocked();
17431        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17432        final boolean wasCached = app.cached;
17433
17434        mAdjSeq++;
17435
17436        // This is the desired cached adjusment we want to tell it to use.
17437        // If our app is currently cached, we know it, and that is it.  Otherwise,
17438        // we don't know it yet, and it needs to now be cached we will then
17439        // need to do a complete oom adj.
17440        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17441                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17442        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17443                SystemClock.uptimeMillis());
17444        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17445            // Changed to/from cached state, so apps after it in the LRU
17446            // list may also be changed.
17447            updateOomAdjLocked();
17448        }
17449        return success;
17450    }
17451
17452    final void updateOomAdjLocked() {
17453        final ActivityRecord TOP_ACT = resumedAppLocked();
17454        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17455        final long now = SystemClock.uptimeMillis();
17456        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17457        final int N = mLruProcesses.size();
17458
17459        if (false) {
17460            RuntimeException e = new RuntimeException();
17461            e.fillInStackTrace();
17462            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17463        }
17464
17465        mAdjSeq++;
17466        mNewNumServiceProcs = 0;
17467        mNewNumAServiceProcs = 0;
17468
17469        final int emptyProcessLimit;
17470        final int cachedProcessLimit;
17471        if (mProcessLimit <= 0) {
17472            emptyProcessLimit = cachedProcessLimit = 0;
17473        } else if (mProcessLimit == 1) {
17474            emptyProcessLimit = 1;
17475            cachedProcessLimit = 0;
17476        } else {
17477            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17478            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17479        }
17480
17481        // Let's determine how many processes we have running vs.
17482        // how many slots we have for background processes; we may want
17483        // to put multiple processes in a slot of there are enough of
17484        // them.
17485        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17486                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17487        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17488        if (numEmptyProcs > cachedProcessLimit) {
17489            // If there are more empty processes than our limit on cached
17490            // processes, then use the cached process limit for the factor.
17491            // This ensures that the really old empty processes get pushed
17492            // down to the bottom, so if we are running low on memory we will
17493            // have a better chance at keeping around more cached processes
17494            // instead of a gazillion empty processes.
17495            numEmptyProcs = cachedProcessLimit;
17496        }
17497        int emptyFactor = numEmptyProcs/numSlots;
17498        if (emptyFactor < 1) emptyFactor = 1;
17499        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17500        if (cachedFactor < 1) cachedFactor = 1;
17501        int stepCached = 0;
17502        int stepEmpty = 0;
17503        int numCached = 0;
17504        int numEmpty = 0;
17505        int numTrimming = 0;
17506
17507        mNumNonCachedProcs = 0;
17508        mNumCachedHiddenProcs = 0;
17509
17510        // First update the OOM adjustment for each of the
17511        // application processes based on their current state.
17512        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17513        int nextCachedAdj = curCachedAdj+1;
17514        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17515        int nextEmptyAdj = curEmptyAdj+2;
17516        for (int i=N-1; i>=0; i--) {
17517            ProcessRecord app = mLruProcesses.get(i);
17518            if (!app.killedByAm && app.thread != null) {
17519                app.procStateChanged = false;
17520                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17521
17522                // If we haven't yet assigned the final cached adj
17523                // to the process, do that now.
17524                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17525                    switch (app.curProcState) {
17526                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17527                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17528                            // This process is a cached process holding activities...
17529                            // assign it the next cached value for that type, and then
17530                            // step that cached level.
17531                            app.curRawAdj = curCachedAdj;
17532                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17533                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17534                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17535                                    + ")");
17536                            if (curCachedAdj != nextCachedAdj) {
17537                                stepCached++;
17538                                if (stepCached >= cachedFactor) {
17539                                    stepCached = 0;
17540                                    curCachedAdj = nextCachedAdj;
17541                                    nextCachedAdj += 2;
17542                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17543                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17544                                    }
17545                                }
17546                            }
17547                            break;
17548                        default:
17549                            // For everything else, assign next empty cached process
17550                            // level and bump that up.  Note that this means that
17551                            // long-running services that have dropped down to the
17552                            // cached level will be treated as empty (since their process
17553                            // state is still as a service), which is what we want.
17554                            app.curRawAdj = curEmptyAdj;
17555                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17556                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17557                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17558                                    + ")");
17559                            if (curEmptyAdj != nextEmptyAdj) {
17560                                stepEmpty++;
17561                                if (stepEmpty >= emptyFactor) {
17562                                    stepEmpty = 0;
17563                                    curEmptyAdj = nextEmptyAdj;
17564                                    nextEmptyAdj += 2;
17565                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17566                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17567                                    }
17568                                }
17569                            }
17570                            break;
17571                    }
17572                }
17573
17574                applyOomAdjLocked(app, TOP_APP, true, now);
17575
17576                // Count the number of process types.
17577                switch (app.curProcState) {
17578                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17579                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17580                        mNumCachedHiddenProcs++;
17581                        numCached++;
17582                        if (numCached > cachedProcessLimit) {
17583                            app.kill("cached #" + numCached, true);
17584                        }
17585                        break;
17586                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17587                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17588                                && app.lastActivityTime < oldTime) {
17589                            app.kill("empty for "
17590                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17591                                    / 1000) + "s", true);
17592                        } else {
17593                            numEmpty++;
17594                            if (numEmpty > emptyProcessLimit) {
17595                                app.kill("empty #" + numEmpty, true);
17596                            }
17597                        }
17598                        break;
17599                    default:
17600                        mNumNonCachedProcs++;
17601                        break;
17602                }
17603
17604                if (app.isolated && app.services.size() <= 0) {
17605                    // If this is an isolated process, and there are no
17606                    // services running in it, then the process is no longer
17607                    // needed.  We agressively kill these because we can by
17608                    // definition not re-use the same process again, and it is
17609                    // good to avoid having whatever code was running in them
17610                    // left sitting around after no longer needed.
17611                    app.kill("isolated not needed", true);
17612                }
17613
17614                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17615                        && !app.killedByAm) {
17616                    numTrimming++;
17617                }
17618            }
17619        }
17620
17621        mNumServiceProcs = mNewNumServiceProcs;
17622
17623        // Now determine the memory trimming level of background processes.
17624        // Unfortunately we need to start at the back of the list to do this
17625        // properly.  We only do this if the number of background apps we
17626        // are managing to keep around is less than half the maximum we desire;
17627        // if we are keeping a good number around, we'll let them use whatever
17628        // memory they want.
17629        final int numCachedAndEmpty = numCached + numEmpty;
17630        int memFactor;
17631        if (numCached <= ProcessList.TRIM_CACHED_APPS
17632                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17633            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17634                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17635            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17636                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17637            } else {
17638                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17639            }
17640        } else {
17641            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17642        }
17643        // We always allow the memory level to go up (better).  We only allow it to go
17644        // down if we are in a state where that is allowed, *and* the total number of processes
17645        // has gone down since last time.
17646        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17647                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17648                + " last=" + mLastNumProcesses);
17649        if (memFactor > mLastMemoryLevel) {
17650            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17651                memFactor = mLastMemoryLevel;
17652                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17653            }
17654        }
17655        mLastMemoryLevel = memFactor;
17656        mLastNumProcesses = mLruProcesses.size();
17657        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17658        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17659        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17660            if (mLowRamStartTime == 0) {
17661                mLowRamStartTime = now;
17662            }
17663            int step = 0;
17664            int fgTrimLevel;
17665            switch (memFactor) {
17666                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17667                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17668                    break;
17669                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17670                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17671                    break;
17672                default:
17673                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17674                    break;
17675            }
17676            int factor = numTrimming/3;
17677            int minFactor = 2;
17678            if (mHomeProcess != null) minFactor++;
17679            if (mPreviousProcess != null) minFactor++;
17680            if (factor < minFactor) factor = minFactor;
17681            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17682            for (int i=N-1; i>=0; i--) {
17683                ProcessRecord app = mLruProcesses.get(i);
17684                if (allChanged || app.procStateChanged) {
17685                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17686                    app.procStateChanged = false;
17687                }
17688                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17689                        && !app.killedByAm) {
17690                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17691                        try {
17692                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17693                                    "Trimming memory of " + app.processName
17694                                    + " to " + curLevel);
17695                            app.thread.scheduleTrimMemory(curLevel);
17696                        } catch (RemoteException e) {
17697                        }
17698                        if (false) {
17699                            // For now we won't do this; our memory trimming seems
17700                            // to be good enough at this point that destroying
17701                            // activities causes more harm than good.
17702                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17703                                    && app != mHomeProcess && app != mPreviousProcess) {
17704                                // Need to do this on its own message because the stack may not
17705                                // be in a consistent state at this point.
17706                                // For these apps we will also finish their activities
17707                                // to help them free memory.
17708                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17709                            }
17710                        }
17711                    }
17712                    app.trimMemoryLevel = curLevel;
17713                    step++;
17714                    if (step >= factor) {
17715                        step = 0;
17716                        switch (curLevel) {
17717                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17718                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17719                                break;
17720                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17721                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17722                                break;
17723                        }
17724                    }
17725                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17726                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17727                            && app.thread != null) {
17728                        try {
17729                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17730                                    "Trimming memory of heavy-weight " + app.processName
17731                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17732                            app.thread.scheduleTrimMemory(
17733                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17734                        } catch (RemoteException e) {
17735                        }
17736                    }
17737                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17738                } else {
17739                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17740                            || app.systemNoUi) && app.pendingUiClean) {
17741                        // If this application is now in the background and it
17742                        // had done UI, then give it the special trim level to
17743                        // have it free UI resources.
17744                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17745                        if (app.trimMemoryLevel < level && app.thread != null) {
17746                            try {
17747                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17748                                        "Trimming memory of bg-ui " + app.processName
17749                                        + " to " + level);
17750                                app.thread.scheduleTrimMemory(level);
17751                            } catch (RemoteException e) {
17752                            }
17753                        }
17754                        app.pendingUiClean = false;
17755                    }
17756                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17757                        try {
17758                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17759                                    "Trimming memory of fg " + app.processName
17760                                    + " to " + fgTrimLevel);
17761                            app.thread.scheduleTrimMemory(fgTrimLevel);
17762                        } catch (RemoteException e) {
17763                        }
17764                    }
17765                    app.trimMemoryLevel = fgTrimLevel;
17766                }
17767            }
17768        } else {
17769            if (mLowRamStartTime != 0) {
17770                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17771                mLowRamStartTime = 0;
17772            }
17773            for (int i=N-1; i>=0; i--) {
17774                ProcessRecord app = mLruProcesses.get(i);
17775                if (allChanged || app.procStateChanged) {
17776                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17777                    app.procStateChanged = false;
17778                }
17779                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17780                        || app.systemNoUi) && app.pendingUiClean) {
17781                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17782                            && app.thread != null) {
17783                        try {
17784                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17785                                    "Trimming memory of ui hidden " + app.processName
17786                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17787                            app.thread.scheduleTrimMemory(
17788                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17789                        } catch (RemoteException e) {
17790                        }
17791                    }
17792                    app.pendingUiClean = false;
17793                }
17794                app.trimMemoryLevel = 0;
17795            }
17796        }
17797
17798        if (mAlwaysFinishActivities) {
17799            // Need to do this on its own message because the stack may not
17800            // be in a consistent state at this point.
17801            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17802        }
17803
17804        if (allChanged) {
17805            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17806        }
17807
17808        if (mProcessStats.shouldWriteNowLocked(now)) {
17809            mHandler.post(new Runnable() {
17810                @Override public void run() {
17811                    synchronized (ActivityManagerService.this) {
17812                        mProcessStats.writeStateAsyncLocked();
17813                    }
17814                }
17815            });
17816        }
17817
17818        if (DEBUG_OOM_ADJ) {
17819            if (false) {
17820                RuntimeException here = new RuntimeException("here");
17821                here.fillInStackTrace();
17822                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17823            } else {
17824                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17825            }
17826        }
17827    }
17828
17829    final void trimApplications() {
17830        synchronized (this) {
17831            int i;
17832
17833            // First remove any unused application processes whose package
17834            // has been removed.
17835            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17836                final ProcessRecord app = mRemovedProcesses.get(i);
17837                if (app.activities.size() == 0
17838                        && app.curReceiver == null && app.services.size() == 0) {
17839                    Slog.i(
17840                        TAG, "Exiting empty application process "
17841                        + app.processName + " ("
17842                        + (app.thread != null ? app.thread.asBinder() : null)
17843                        + ")\n");
17844                    if (app.pid > 0 && app.pid != MY_PID) {
17845                        app.kill("empty", false);
17846                    } else {
17847                        try {
17848                            app.thread.scheduleExit();
17849                        } catch (Exception e) {
17850                            // Ignore exceptions.
17851                        }
17852                    }
17853                    cleanUpApplicationRecordLocked(app, false, true, -1);
17854                    mRemovedProcesses.remove(i);
17855
17856                    if (app.persistent) {
17857                        addAppLocked(app.info, false, null /* ABI override */);
17858                    }
17859                }
17860            }
17861
17862            // Now update the oom adj for all processes.
17863            updateOomAdjLocked();
17864        }
17865    }
17866
17867    /** This method sends the specified signal to each of the persistent apps */
17868    public void signalPersistentProcesses(int sig) throws RemoteException {
17869        if (sig != Process.SIGNAL_USR1) {
17870            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17871        }
17872
17873        synchronized (this) {
17874            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17875                    != PackageManager.PERMISSION_GRANTED) {
17876                throw new SecurityException("Requires permission "
17877                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17878            }
17879
17880            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17881                ProcessRecord r = mLruProcesses.get(i);
17882                if (r.thread != null && r.persistent) {
17883                    Process.sendSignal(r.pid, sig);
17884                }
17885            }
17886        }
17887    }
17888
17889    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17890        if (proc == null || proc == mProfileProc) {
17891            proc = mProfileProc;
17892            profileType = mProfileType;
17893            clearProfilerLocked();
17894        }
17895        if (proc == null) {
17896            return;
17897        }
17898        try {
17899            proc.thread.profilerControl(false, null, profileType);
17900        } catch (RemoteException e) {
17901            throw new IllegalStateException("Process disappeared");
17902        }
17903    }
17904
17905    private void clearProfilerLocked() {
17906        if (mProfileFd != null) {
17907            try {
17908                mProfileFd.close();
17909            } catch (IOException e) {
17910            }
17911        }
17912        mProfileApp = null;
17913        mProfileProc = null;
17914        mProfileFile = null;
17915        mProfileType = 0;
17916        mAutoStopProfiler = false;
17917        mSamplingInterval = 0;
17918    }
17919
17920    public boolean profileControl(String process, int userId, boolean start,
17921            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17922
17923        try {
17924            synchronized (this) {
17925                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17926                // its own permission.
17927                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17928                        != PackageManager.PERMISSION_GRANTED) {
17929                    throw new SecurityException("Requires permission "
17930                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17931                }
17932
17933                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17934                    throw new IllegalArgumentException("null profile info or fd");
17935                }
17936
17937                ProcessRecord proc = null;
17938                if (process != null) {
17939                    proc = findProcessLocked(process, userId, "profileControl");
17940                }
17941
17942                if (start && (proc == null || proc.thread == null)) {
17943                    throw new IllegalArgumentException("Unknown process: " + process);
17944                }
17945
17946                if (start) {
17947                    stopProfilerLocked(null, 0);
17948                    setProfileApp(proc.info, proc.processName, profilerInfo);
17949                    mProfileProc = proc;
17950                    mProfileType = profileType;
17951                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17952                    try {
17953                        fd = fd.dup();
17954                    } catch (IOException e) {
17955                        fd = null;
17956                    }
17957                    profilerInfo.profileFd = fd;
17958                    proc.thread.profilerControl(start, profilerInfo, profileType);
17959                    fd = null;
17960                    mProfileFd = null;
17961                } else {
17962                    stopProfilerLocked(proc, profileType);
17963                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17964                        try {
17965                            profilerInfo.profileFd.close();
17966                        } catch (IOException e) {
17967                        }
17968                    }
17969                }
17970
17971                return true;
17972            }
17973        } catch (RemoteException e) {
17974            throw new IllegalStateException("Process disappeared");
17975        } finally {
17976            if (profilerInfo != null && profilerInfo.profileFd != null) {
17977                try {
17978                    profilerInfo.profileFd.close();
17979                } catch (IOException e) {
17980                }
17981            }
17982        }
17983    }
17984
17985    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17986        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17987                userId, true, ALLOW_FULL_ONLY, callName, null);
17988        ProcessRecord proc = null;
17989        try {
17990            int pid = Integer.parseInt(process);
17991            synchronized (mPidsSelfLocked) {
17992                proc = mPidsSelfLocked.get(pid);
17993            }
17994        } catch (NumberFormatException e) {
17995        }
17996
17997        if (proc == null) {
17998            ArrayMap<String, SparseArray<ProcessRecord>> all
17999                    = mProcessNames.getMap();
18000            SparseArray<ProcessRecord> procs = all.get(process);
18001            if (procs != null && procs.size() > 0) {
18002                proc = procs.valueAt(0);
18003                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18004                    for (int i=1; i<procs.size(); i++) {
18005                        ProcessRecord thisProc = procs.valueAt(i);
18006                        if (thisProc.userId == userId) {
18007                            proc = thisProc;
18008                            break;
18009                        }
18010                    }
18011                }
18012            }
18013        }
18014
18015        return proc;
18016    }
18017
18018    public boolean dumpHeap(String process, int userId, boolean managed,
18019            String path, ParcelFileDescriptor fd) throws RemoteException {
18020
18021        try {
18022            synchronized (this) {
18023                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18024                // its own permission (same as profileControl).
18025                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18026                        != PackageManager.PERMISSION_GRANTED) {
18027                    throw new SecurityException("Requires permission "
18028                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18029                }
18030
18031                if (fd == null) {
18032                    throw new IllegalArgumentException("null fd");
18033                }
18034
18035                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18036                if (proc == null || proc.thread == null) {
18037                    throw new IllegalArgumentException("Unknown process: " + process);
18038                }
18039
18040                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18041                if (!isDebuggable) {
18042                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18043                        throw new SecurityException("Process not debuggable: " + proc);
18044                    }
18045                }
18046
18047                proc.thread.dumpHeap(managed, path, fd);
18048                fd = null;
18049                return true;
18050            }
18051        } catch (RemoteException e) {
18052            throw new IllegalStateException("Process disappeared");
18053        } finally {
18054            if (fd != null) {
18055                try {
18056                    fd.close();
18057                } catch (IOException e) {
18058                }
18059            }
18060        }
18061    }
18062
18063    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18064    public void monitor() {
18065        synchronized (this) { }
18066    }
18067
18068    void onCoreSettingsChange(Bundle settings) {
18069        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18070            ProcessRecord processRecord = mLruProcesses.get(i);
18071            try {
18072                if (processRecord.thread != null) {
18073                    processRecord.thread.setCoreSettings(settings);
18074                }
18075            } catch (RemoteException re) {
18076                /* ignore */
18077            }
18078        }
18079    }
18080
18081    // Multi-user methods
18082
18083    /**
18084     * Start user, if its not already running, but don't bring it to foreground.
18085     */
18086    @Override
18087    public boolean startUserInBackground(final int userId) {
18088        return startUser(userId, /* foreground */ false);
18089    }
18090
18091    /**
18092     * Start user, if its not already running, and bring it to foreground.
18093     */
18094    boolean startUserInForeground(final int userId, Dialog dlg) {
18095        boolean result = startUser(userId, /* foreground */ true);
18096        dlg.dismiss();
18097        return result;
18098    }
18099
18100    /**
18101     * Refreshes the list of users related to the current user when either a
18102     * user switch happens or when a new related user is started in the
18103     * background.
18104     */
18105    private void updateCurrentProfileIdsLocked() {
18106        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18107                mCurrentUserId, false /* enabledOnly */);
18108        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18109        for (int i = 0; i < currentProfileIds.length; i++) {
18110            currentProfileIds[i] = profiles.get(i).id;
18111        }
18112        mCurrentProfileIds = currentProfileIds;
18113
18114        synchronized (mUserProfileGroupIdsSelfLocked) {
18115            mUserProfileGroupIdsSelfLocked.clear();
18116            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18117            for (int i = 0; i < users.size(); i++) {
18118                UserInfo user = users.get(i);
18119                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18120                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18121                }
18122            }
18123        }
18124    }
18125
18126    private Set getProfileIdsLocked(int userId) {
18127        Set userIds = new HashSet<Integer>();
18128        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18129                userId, false /* enabledOnly */);
18130        for (UserInfo user : profiles) {
18131            userIds.add(Integer.valueOf(user.id));
18132        }
18133        return userIds;
18134    }
18135
18136    @Override
18137    public boolean switchUser(final int userId) {
18138        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18139        String userName;
18140        synchronized (this) {
18141            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18142            if (userInfo == null) {
18143                Slog.w(TAG, "No user info for user #" + userId);
18144                return false;
18145            }
18146            if (userInfo.isManagedProfile()) {
18147                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18148                return false;
18149            }
18150            userName = userInfo.name;
18151            mTargetUserId = userId;
18152        }
18153        mHandler.removeMessages(START_USER_SWITCH_MSG);
18154        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18155        return true;
18156    }
18157
18158    private void showUserSwitchDialog(int userId, String userName) {
18159        // The dialog will show and then initiate the user switch by calling startUserInForeground
18160        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18161                true /* above system */);
18162        d.show();
18163    }
18164
18165    private boolean startUser(final int userId, final boolean foreground) {
18166        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18167                != PackageManager.PERMISSION_GRANTED) {
18168            String msg = "Permission Denial: switchUser() from pid="
18169                    + Binder.getCallingPid()
18170                    + ", uid=" + Binder.getCallingUid()
18171                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18172            Slog.w(TAG, msg);
18173            throw new SecurityException(msg);
18174        }
18175
18176        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18177
18178        final long ident = Binder.clearCallingIdentity();
18179        try {
18180            synchronized (this) {
18181                final int oldUserId = mCurrentUserId;
18182                if (oldUserId == userId) {
18183                    return true;
18184                }
18185
18186                mStackSupervisor.setLockTaskModeLocked(null, false);
18187
18188                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18189                if (userInfo == null) {
18190                    Slog.w(TAG, "No user info for user #" + userId);
18191                    return false;
18192                }
18193                if (foreground && userInfo.isManagedProfile()) {
18194                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18195                    return false;
18196                }
18197
18198                if (foreground) {
18199                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18200                            R.anim.screen_user_enter);
18201                }
18202
18203                boolean needStart = false;
18204
18205                // If the user we are switching to is not currently started, then
18206                // we need to start it now.
18207                if (mStartedUsers.get(userId) == null) {
18208                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18209                    updateStartedUserArrayLocked();
18210                    needStart = true;
18211                }
18212
18213                final Integer userIdInt = Integer.valueOf(userId);
18214                mUserLru.remove(userIdInt);
18215                mUserLru.add(userIdInt);
18216
18217                if (foreground) {
18218                    mCurrentUserId = userId;
18219                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18220                    updateCurrentProfileIdsLocked();
18221                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18222                    // Once the internal notion of the active user has switched, we lock the device
18223                    // with the option to show the user switcher on the keyguard.
18224                    mWindowManager.lockNow(null);
18225                } else {
18226                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18227                    updateCurrentProfileIdsLocked();
18228                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18229                    mUserLru.remove(currentUserIdInt);
18230                    mUserLru.add(currentUserIdInt);
18231                }
18232
18233                final UserStartedState uss = mStartedUsers.get(userId);
18234
18235                // Make sure user is in the started state.  If it is currently
18236                // stopping, we need to knock that off.
18237                if (uss.mState == UserStartedState.STATE_STOPPING) {
18238                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18239                    // so we can just fairly silently bring the user back from
18240                    // the almost-dead.
18241                    uss.mState = UserStartedState.STATE_RUNNING;
18242                    updateStartedUserArrayLocked();
18243                    needStart = true;
18244                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18245                    // This means ACTION_SHUTDOWN has been sent, so we will
18246                    // need to treat this as a new boot of the user.
18247                    uss.mState = UserStartedState.STATE_BOOTING;
18248                    updateStartedUserArrayLocked();
18249                    needStart = true;
18250                }
18251
18252                if (uss.mState == UserStartedState.STATE_BOOTING) {
18253                    // Booting up a new user, need to tell system services about it.
18254                    // Note that this is on the same handler as scheduling of broadcasts,
18255                    // which is important because it needs to go first.
18256                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18257                }
18258
18259                if (foreground) {
18260                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18261                            oldUserId));
18262                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18263                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18264                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18265                            oldUserId, userId, uss));
18266                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18267                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18268                }
18269
18270                if (needStart) {
18271                    // Send USER_STARTED broadcast
18272                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18273                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18274                            | Intent.FLAG_RECEIVER_FOREGROUND);
18275                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18276                    broadcastIntentLocked(null, null, intent,
18277                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18278                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18279                }
18280
18281                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18282                    if (userId != UserHandle.USER_OWNER) {
18283                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18284                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18285                        broadcastIntentLocked(null, null, intent, null,
18286                                new IIntentReceiver.Stub() {
18287                                    public void performReceive(Intent intent, int resultCode,
18288                                            String data, Bundle extras, boolean ordered,
18289                                            boolean sticky, int sendingUser) {
18290                                        onUserInitialized(uss, foreground, oldUserId, userId);
18291                                    }
18292                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18293                                true, false, MY_PID, Process.SYSTEM_UID,
18294                                userId);
18295                        uss.initializing = true;
18296                    } else {
18297                        getUserManagerLocked().makeInitialized(userInfo.id);
18298                    }
18299                }
18300
18301                if (foreground) {
18302                    if (!uss.initializing) {
18303                        moveUserToForeground(uss, oldUserId, userId);
18304                    }
18305                } else {
18306                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18307                }
18308
18309                if (needStart) {
18310                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18311                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18312                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18313                    broadcastIntentLocked(null, null, intent,
18314                            null, new IIntentReceiver.Stub() {
18315                                @Override
18316                                public void performReceive(Intent intent, int resultCode, String data,
18317                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18318                                        throws RemoteException {
18319                                }
18320                            }, 0, null, null,
18321                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18322                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18323                }
18324            }
18325        } finally {
18326            Binder.restoreCallingIdentity(ident);
18327        }
18328
18329        return true;
18330    }
18331
18332    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18333        long ident = Binder.clearCallingIdentity();
18334        try {
18335            Intent intent;
18336            if (oldUserId >= 0) {
18337                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18338                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18339                int count = profiles.size();
18340                for (int i = 0; i < count; i++) {
18341                    int profileUserId = profiles.get(i).id;
18342                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18343                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18344                            | Intent.FLAG_RECEIVER_FOREGROUND);
18345                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18346                    broadcastIntentLocked(null, null, intent,
18347                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18348                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18349                }
18350            }
18351            if (newUserId >= 0) {
18352                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18353                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18354                int count = profiles.size();
18355                for (int i = 0; i < count; i++) {
18356                    int profileUserId = profiles.get(i).id;
18357                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18358                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18359                            | Intent.FLAG_RECEIVER_FOREGROUND);
18360                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18361                    broadcastIntentLocked(null, null, intent,
18362                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18363                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18364                }
18365                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18366                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18367                        | Intent.FLAG_RECEIVER_FOREGROUND);
18368                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18369                broadcastIntentLocked(null, null, intent,
18370                        null, null, 0, null, null,
18371                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18372                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18373            }
18374        } finally {
18375            Binder.restoreCallingIdentity(ident);
18376        }
18377    }
18378
18379    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18380            final int newUserId) {
18381        final int N = mUserSwitchObservers.beginBroadcast();
18382        if (N > 0) {
18383            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18384                int mCount = 0;
18385                @Override
18386                public void sendResult(Bundle data) throws RemoteException {
18387                    synchronized (ActivityManagerService.this) {
18388                        if (mCurUserSwitchCallback == this) {
18389                            mCount++;
18390                            if (mCount == N) {
18391                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18392                            }
18393                        }
18394                    }
18395                }
18396            };
18397            synchronized (this) {
18398                uss.switching = true;
18399                mCurUserSwitchCallback = callback;
18400            }
18401            for (int i=0; i<N; i++) {
18402                try {
18403                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18404                            newUserId, callback);
18405                } catch (RemoteException e) {
18406                }
18407            }
18408        } else {
18409            synchronized (this) {
18410                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18411            }
18412        }
18413        mUserSwitchObservers.finishBroadcast();
18414    }
18415
18416    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18417        synchronized (this) {
18418            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18419            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18420        }
18421    }
18422
18423    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18424        mCurUserSwitchCallback = null;
18425        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18426        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18427                oldUserId, newUserId, uss));
18428    }
18429
18430    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18431        synchronized (this) {
18432            if (foreground) {
18433                moveUserToForeground(uss, oldUserId, newUserId);
18434            }
18435        }
18436
18437        completeSwitchAndInitalize(uss, newUserId, true, false);
18438    }
18439
18440    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18441        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18442        if (homeInFront) {
18443            startHomeActivityLocked(newUserId);
18444        } else {
18445            mStackSupervisor.resumeTopActivitiesLocked();
18446        }
18447        EventLogTags.writeAmSwitchUser(newUserId);
18448        getUserManagerLocked().userForeground(newUserId);
18449        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18450    }
18451
18452    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18453        completeSwitchAndInitalize(uss, newUserId, false, true);
18454    }
18455
18456    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18457            boolean clearInitializing, boolean clearSwitching) {
18458        boolean unfrozen = false;
18459        synchronized (this) {
18460            if (clearInitializing) {
18461                uss.initializing = false;
18462                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18463            }
18464            if (clearSwitching) {
18465                uss.switching = false;
18466            }
18467            if (!uss.switching && !uss.initializing) {
18468                mWindowManager.stopFreezingScreen();
18469                unfrozen = true;
18470            }
18471        }
18472        if (unfrozen) {
18473            final int N = mUserSwitchObservers.beginBroadcast();
18474            for (int i=0; i<N; i++) {
18475                try {
18476                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18477                } catch (RemoteException e) {
18478                }
18479            }
18480            mUserSwitchObservers.finishBroadcast();
18481        }
18482    }
18483
18484    void scheduleStartProfilesLocked() {
18485        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18486            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18487                    DateUtils.SECOND_IN_MILLIS);
18488        }
18489    }
18490
18491    void startProfilesLocked() {
18492        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18493        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18494                mCurrentUserId, false /* enabledOnly */);
18495        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18496        for (UserInfo user : profiles) {
18497            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18498                    && user.id != mCurrentUserId) {
18499                toStart.add(user);
18500            }
18501        }
18502        final int n = toStart.size();
18503        int i = 0;
18504        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18505            startUserInBackground(toStart.get(i).id);
18506        }
18507        if (i < n) {
18508            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18509        }
18510    }
18511
18512    void finishUserBoot(UserStartedState uss) {
18513        synchronized (this) {
18514            if (uss.mState == UserStartedState.STATE_BOOTING
18515                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18516                uss.mState = UserStartedState.STATE_RUNNING;
18517                final int userId = uss.mHandle.getIdentifier();
18518                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18519                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18520                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18521                broadcastIntentLocked(null, null, intent,
18522                        null, null, 0, null, null,
18523                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18524                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18525            }
18526        }
18527    }
18528
18529    void finishUserSwitch(UserStartedState uss) {
18530        synchronized (this) {
18531            finishUserBoot(uss);
18532
18533            startProfilesLocked();
18534
18535            int num = mUserLru.size();
18536            int i = 0;
18537            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18538                Integer oldUserId = mUserLru.get(i);
18539                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18540                if (oldUss == null) {
18541                    // Shouldn't happen, but be sane if it does.
18542                    mUserLru.remove(i);
18543                    num--;
18544                    continue;
18545                }
18546                if (oldUss.mState == UserStartedState.STATE_STOPPING
18547                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18548                    // This user is already stopping, doesn't count.
18549                    num--;
18550                    i++;
18551                    continue;
18552                }
18553                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18554                    // Owner and current can't be stopped, but count as running.
18555                    i++;
18556                    continue;
18557                }
18558                // This is a user to be stopped.
18559                stopUserLocked(oldUserId, null);
18560                num--;
18561                i++;
18562            }
18563        }
18564    }
18565
18566    @Override
18567    public int stopUser(final int userId, final IStopUserCallback callback) {
18568        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18569                != PackageManager.PERMISSION_GRANTED) {
18570            String msg = "Permission Denial: switchUser() from pid="
18571                    + Binder.getCallingPid()
18572                    + ", uid=" + Binder.getCallingUid()
18573                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18574            Slog.w(TAG, msg);
18575            throw new SecurityException(msg);
18576        }
18577        if (userId <= 0) {
18578            throw new IllegalArgumentException("Can't stop primary user " + userId);
18579        }
18580        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18581        synchronized (this) {
18582            return stopUserLocked(userId, callback);
18583        }
18584    }
18585
18586    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18587        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18588        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18589            return ActivityManager.USER_OP_IS_CURRENT;
18590        }
18591
18592        final UserStartedState uss = mStartedUsers.get(userId);
18593        if (uss == null) {
18594            // User is not started, nothing to do...  but we do need to
18595            // callback if requested.
18596            if (callback != null) {
18597                mHandler.post(new Runnable() {
18598                    @Override
18599                    public void run() {
18600                        try {
18601                            callback.userStopped(userId);
18602                        } catch (RemoteException e) {
18603                        }
18604                    }
18605                });
18606            }
18607            return ActivityManager.USER_OP_SUCCESS;
18608        }
18609
18610        if (callback != null) {
18611            uss.mStopCallbacks.add(callback);
18612        }
18613
18614        if (uss.mState != UserStartedState.STATE_STOPPING
18615                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18616            uss.mState = UserStartedState.STATE_STOPPING;
18617            updateStartedUserArrayLocked();
18618
18619            long ident = Binder.clearCallingIdentity();
18620            try {
18621                // We are going to broadcast ACTION_USER_STOPPING and then
18622                // once that is done send a final ACTION_SHUTDOWN and then
18623                // stop the user.
18624                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18625                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18626                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18627                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18628                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18629                // This is the result receiver for the final shutdown broadcast.
18630                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18631                    @Override
18632                    public void performReceive(Intent intent, int resultCode, String data,
18633                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18634                        finishUserStop(uss);
18635                    }
18636                };
18637                // This is the result receiver for the initial stopping broadcast.
18638                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18639                    @Override
18640                    public void performReceive(Intent intent, int resultCode, String data,
18641                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18642                        // On to the next.
18643                        synchronized (ActivityManagerService.this) {
18644                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18645                                // Whoops, we are being started back up.  Abort, abort!
18646                                return;
18647                            }
18648                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18649                        }
18650                        mBatteryStatsService.noteEvent(
18651                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18652                                Integer.toString(userId), userId);
18653                        mSystemServiceManager.stopUser(userId);
18654                        broadcastIntentLocked(null, null, shutdownIntent,
18655                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18656                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18657                    }
18658                };
18659                // Kick things off.
18660                broadcastIntentLocked(null, null, stoppingIntent,
18661                        null, stoppingReceiver, 0, null, null,
18662                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18663                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18664            } finally {
18665                Binder.restoreCallingIdentity(ident);
18666            }
18667        }
18668
18669        return ActivityManager.USER_OP_SUCCESS;
18670    }
18671
18672    void finishUserStop(UserStartedState uss) {
18673        final int userId = uss.mHandle.getIdentifier();
18674        boolean stopped;
18675        ArrayList<IStopUserCallback> callbacks;
18676        synchronized (this) {
18677            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18678            if (mStartedUsers.get(userId) != uss) {
18679                stopped = false;
18680            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18681                stopped = false;
18682            } else {
18683                stopped = true;
18684                // User can no longer run.
18685                mStartedUsers.remove(userId);
18686                mUserLru.remove(Integer.valueOf(userId));
18687                updateStartedUserArrayLocked();
18688
18689                // Clean up all state and processes associated with the user.
18690                // Kill all the processes for the user.
18691                forceStopUserLocked(userId, "finish user");
18692            }
18693
18694            // Explicitly remove the old information in mRecentTasks.
18695            removeRecentTasksForUserLocked(userId);
18696        }
18697
18698        for (int i=0; i<callbacks.size(); i++) {
18699            try {
18700                if (stopped) callbacks.get(i).userStopped(userId);
18701                else callbacks.get(i).userStopAborted(userId);
18702            } catch (RemoteException e) {
18703            }
18704        }
18705
18706        if (stopped) {
18707            mSystemServiceManager.cleanupUser(userId);
18708            synchronized (this) {
18709                mStackSupervisor.removeUserLocked(userId);
18710            }
18711        }
18712    }
18713
18714    @Override
18715    public UserInfo getCurrentUser() {
18716        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18717                != PackageManager.PERMISSION_GRANTED) && (
18718                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18719                != PackageManager.PERMISSION_GRANTED)) {
18720            String msg = "Permission Denial: getCurrentUser() from pid="
18721                    + Binder.getCallingPid()
18722                    + ", uid=" + Binder.getCallingUid()
18723                    + " requires " + INTERACT_ACROSS_USERS;
18724            Slog.w(TAG, msg);
18725            throw new SecurityException(msg);
18726        }
18727        synchronized (this) {
18728            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18729            return getUserManagerLocked().getUserInfo(userId);
18730        }
18731    }
18732
18733    int getCurrentUserIdLocked() {
18734        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18735    }
18736
18737    @Override
18738    public boolean isUserRunning(int userId, boolean orStopped) {
18739        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18740                != PackageManager.PERMISSION_GRANTED) {
18741            String msg = "Permission Denial: isUserRunning() from pid="
18742                    + Binder.getCallingPid()
18743                    + ", uid=" + Binder.getCallingUid()
18744                    + " requires " + INTERACT_ACROSS_USERS;
18745            Slog.w(TAG, msg);
18746            throw new SecurityException(msg);
18747        }
18748        synchronized (this) {
18749            return isUserRunningLocked(userId, orStopped);
18750        }
18751    }
18752
18753    boolean isUserRunningLocked(int userId, boolean orStopped) {
18754        UserStartedState state = mStartedUsers.get(userId);
18755        if (state == null) {
18756            return false;
18757        }
18758        if (orStopped) {
18759            return true;
18760        }
18761        return state.mState != UserStartedState.STATE_STOPPING
18762                && state.mState != UserStartedState.STATE_SHUTDOWN;
18763    }
18764
18765    @Override
18766    public int[] getRunningUserIds() {
18767        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18768                != PackageManager.PERMISSION_GRANTED) {
18769            String msg = "Permission Denial: isUserRunning() from pid="
18770                    + Binder.getCallingPid()
18771                    + ", uid=" + Binder.getCallingUid()
18772                    + " requires " + INTERACT_ACROSS_USERS;
18773            Slog.w(TAG, msg);
18774            throw new SecurityException(msg);
18775        }
18776        synchronized (this) {
18777            return mStartedUserArray;
18778        }
18779    }
18780
18781    private void updateStartedUserArrayLocked() {
18782        int num = 0;
18783        for (int i=0; i<mStartedUsers.size();  i++) {
18784            UserStartedState uss = mStartedUsers.valueAt(i);
18785            // This list does not include stopping users.
18786            if (uss.mState != UserStartedState.STATE_STOPPING
18787                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18788                num++;
18789            }
18790        }
18791        mStartedUserArray = new int[num];
18792        num = 0;
18793        for (int i=0; i<mStartedUsers.size();  i++) {
18794            UserStartedState uss = mStartedUsers.valueAt(i);
18795            if (uss.mState != UserStartedState.STATE_STOPPING
18796                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18797                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18798                num++;
18799            }
18800        }
18801    }
18802
18803    @Override
18804    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18805        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18806                != PackageManager.PERMISSION_GRANTED) {
18807            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18808                    + Binder.getCallingPid()
18809                    + ", uid=" + Binder.getCallingUid()
18810                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18811            Slog.w(TAG, msg);
18812            throw new SecurityException(msg);
18813        }
18814
18815        mUserSwitchObservers.register(observer);
18816    }
18817
18818    @Override
18819    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18820        mUserSwitchObservers.unregister(observer);
18821    }
18822
18823    private boolean userExists(int userId) {
18824        if (userId == 0) {
18825            return true;
18826        }
18827        UserManagerService ums = getUserManagerLocked();
18828        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18829    }
18830
18831    int[] getUsersLocked() {
18832        UserManagerService ums = getUserManagerLocked();
18833        return ums != null ? ums.getUserIds() : new int[] { 0 };
18834    }
18835
18836    UserManagerService getUserManagerLocked() {
18837        if (mUserManager == null) {
18838            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18839            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18840        }
18841        return mUserManager;
18842    }
18843
18844    private int applyUserId(int uid, int userId) {
18845        return UserHandle.getUid(userId, uid);
18846    }
18847
18848    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18849        if (info == null) return null;
18850        ApplicationInfo newInfo = new ApplicationInfo(info);
18851        newInfo.uid = applyUserId(info.uid, userId);
18852        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18853                + info.packageName;
18854        return newInfo;
18855    }
18856
18857    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18858        if (aInfo == null
18859                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18860            return aInfo;
18861        }
18862
18863        ActivityInfo info = new ActivityInfo(aInfo);
18864        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18865        return info;
18866    }
18867
18868    private final class LocalService extends ActivityManagerInternal {
18869        @Override
18870        public void goingToSleep() {
18871            ActivityManagerService.this.goingToSleep();
18872        }
18873
18874        @Override
18875        public void wakingUp() {
18876            ActivityManagerService.this.wakingUp();
18877        }
18878
18879        @Override
18880        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18881                String processName, String abiOverride, int uid, Runnable crashHandler) {
18882            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18883                    processName, abiOverride, uid, crashHandler);
18884        }
18885    }
18886
18887    /**
18888     * An implementation of IAppTask, that allows an app to manage its own tasks via
18889     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18890     * only the process that calls getAppTasks() can call the AppTask methods.
18891     */
18892    class AppTaskImpl extends IAppTask.Stub {
18893        private int mTaskId;
18894        private int mCallingUid;
18895
18896        public AppTaskImpl(int taskId, int callingUid) {
18897            mTaskId = taskId;
18898            mCallingUid = callingUid;
18899        }
18900
18901        private void checkCaller() {
18902            if (mCallingUid != Binder.getCallingUid()) {
18903                throw new SecurityException("Caller " + mCallingUid
18904                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18905            }
18906        }
18907
18908        @Override
18909        public void finishAndRemoveTask() {
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                    // Only kill the process if we are not a new document
18920                    int flags = tr.getBaseIntent().getFlags();
18921                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18922                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18923                    removeTaskByIdLocked(mTaskId,
18924                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18925                } finally {
18926                    Binder.restoreCallingIdentity(origId);
18927                }
18928            }
18929        }
18930
18931        @Override
18932        public ActivityManager.RecentTaskInfo getTaskInfo() {
18933            checkCaller();
18934
18935            synchronized (ActivityManagerService.this) {
18936                long origId = Binder.clearCallingIdentity();
18937                try {
18938                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18939                    if (tr == null) {
18940                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18941                    }
18942                    return createRecentTaskInfoFromTaskRecord(tr);
18943                } finally {
18944                    Binder.restoreCallingIdentity(origId);
18945                }
18946            }
18947        }
18948
18949        @Override
18950        public void moveToFront() {
18951            checkCaller();
18952
18953            final TaskRecord tr;
18954            synchronized (ActivityManagerService.this) {
18955                tr = recentTaskForIdLocked(mTaskId);
18956                if (tr == null) {
18957                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18958                }
18959                if (tr.getRootActivity() != null) {
18960                    moveTaskToFrontLocked(tr.taskId, 0, null);
18961                }
18962            }
18963
18964            startActivityFromRecentsInner(tr.taskId, null);
18965        }
18966
18967        @Override
18968        public int startActivity(IBinder whoThread, String callingPackage,
18969                Intent intent, String resolvedType, Bundle options) {
18970            checkCaller();
18971
18972            int callingUser = UserHandle.getCallingUserId();
18973            TaskRecord tr;
18974            IApplicationThread appThread;
18975            synchronized (ActivityManagerService.this) {
18976                tr = recentTaskForIdLocked(mTaskId);
18977                if (tr == null) {
18978                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18979                }
18980                appThread = ApplicationThreadNative.asInterface(whoThread);
18981                if (appThread == null) {
18982                    throw new IllegalArgumentException("Bad app thread " + appThread);
18983                }
18984            }
18985            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18986                    resolvedType, null, null, null, null, 0, 0, null, null,
18987                    null, options, callingUser, null, tr);
18988        }
18989
18990        @Override
18991        public void setExcludeFromRecents(boolean exclude) {
18992            checkCaller();
18993
18994            synchronized (ActivityManagerService.this) {
18995                long origId = Binder.clearCallingIdentity();
18996                try {
18997                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18998                    if (tr == null) {
18999                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19000                    }
19001                    Intent intent = tr.getBaseIntent();
19002                    if (exclude) {
19003                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19004                    } else {
19005                        intent.setFlags(intent.getFlags()
19006                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19007                    }
19008                } finally {
19009                    Binder.restoreCallingIdentity(origId);
19010                }
19011            }
19012        }
19013    }
19014}
19015