ActivityManagerService.java revision ff072725e39b8c6928d6ca2d7e263d7d081a2288
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 (!app.killed) {
2620                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2621                Process.killProcessQuiet(app.pid);
2622                Process.killProcessGroup(app.info.uid, app.pid);
2623            }
2624            if (lrui <= mLruProcessActivityStart) {
2625                mLruProcessActivityStart--;
2626            }
2627            if (lrui <= mLruProcessServiceStart) {
2628                mLruProcessServiceStart--;
2629            }
2630            mLruProcesses.remove(lrui);
2631        }
2632    }
2633
2634    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2635            ProcessRecord client) {
2636        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2637                || app.treatLikeActivity;
2638        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2639        if (!activityChange && hasActivity) {
2640            // The process has activities, so we are only allowing activity-based adjustments
2641            // to move it.  It should be kept in the front of the list with other
2642            // processes that have activities, and we don't want those to change their
2643            // order except due to activity operations.
2644            return;
2645        }
2646
2647        mLruSeq++;
2648        final long now = SystemClock.uptimeMillis();
2649        app.lastActivityTime = now;
2650
2651        // First a quick reject: if the app is already at the position we will
2652        // put it, then there is nothing to do.
2653        if (hasActivity) {
2654            final int N = mLruProcesses.size();
2655            if (N > 0 && mLruProcesses.get(N-1) == app) {
2656                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2657                return;
2658            }
2659        } else {
2660            if (mLruProcessServiceStart > 0
2661                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2662                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2663                return;
2664            }
2665        }
2666
2667        int lrui = mLruProcesses.lastIndexOf(app);
2668
2669        if (app.persistent && lrui >= 0) {
2670            // We don't care about the position of persistent processes, as long as
2671            // they are in the list.
2672            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2673            return;
2674        }
2675
2676        /* In progress: compute new position first, so we can avoid doing work
2677           if the process is not actually going to move.  Not yet working.
2678        int addIndex;
2679        int nextIndex;
2680        boolean inActivity = false, inService = false;
2681        if (hasActivity) {
2682            // Process has activities, put it at the very tipsy-top.
2683            addIndex = mLruProcesses.size();
2684            nextIndex = mLruProcessServiceStart;
2685            inActivity = true;
2686        } else if (hasService) {
2687            // Process has services, put it at the top of the service list.
2688            addIndex = mLruProcessActivityStart;
2689            nextIndex = mLruProcessServiceStart;
2690            inActivity = true;
2691            inService = true;
2692        } else  {
2693            // Process not otherwise of interest, it goes to the top of the non-service area.
2694            addIndex = mLruProcessServiceStart;
2695            if (client != null) {
2696                int clientIndex = mLruProcesses.lastIndexOf(client);
2697                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2698                        + app);
2699                if (clientIndex >= 0 && addIndex > clientIndex) {
2700                    addIndex = clientIndex;
2701                }
2702            }
2703            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2704        }
2705
2706        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2707                + mLruProcessActivityStart + "): " + app);
2708        */
2709
2710        if (lrui >= 0) {
2711            if (lrui < mLruProcessActivityStart) {
2712                mLruProcessActivityStart--;
2713            }
2714            if (lrui < mLruProcessServiceStart) {
2715                mLruProcessServiceStart--;
2716            }
2717            /*
2718            if (addIndex > lrui) {
2719                addIndex--;
2720            }
2721            if (nextIndex > lrui) {
2722                nextIndex--;
2723            }
2724            */
2725            mLruProcesses.remove(lrui);
2726        }
2727
2728        /*
2729        mLruProcesses.add(addIndex, app);
2730        if (inActivity) {
2731            mLruProcessActivityStart++;
2732        }
2733        if (inService) {
2734            mLruProcessActivityStart++;
2735        }
2736        */
2737
2738        int nextIndex;
2739        if (hasActivity) {
2740            final int N = mLruProcesses.size();
2741            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2742                // Process doesn't have activities, but has clients with
2743                // activities...  move it up, but one below the top (the top
2744                // should always have a real activity).
2745                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2746                mLruProcesses.add(N-1, app);
2747                // To keep it from spamming the LRU list (by making a bunch of clients),
2748                // we will push down any other entries owned by the app.
2749                final int uid = app.info.uid;
2750                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2751                    ProcessRecord subProc = mLruProcesses.get(i);
2752                    if (subProc.info.uid == uid) {
2753                        // We want to push this one down the list.  If the process after
2754                        // it is for the same uid, however, don't do so, because we don't
2755                        // want them internally to be re-ordered.
2756                        if (mLruProcesses.get(i-1).info.uid != uid) {
2757                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2758                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2759                            ProcessRecord tmp = mLruProcesses.get(i);
2760                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2761                            mLruProcesses.set(i-1, tmp);
2762                            i--;
2763                        }
2764                    } else {
2765                        // A gap, we can stop here.
2766                        break;
2767                    }
2768                }
2769            } else {
2770                // Process has activities, put it at the very tipsy-top.
2771                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2772                mLruProcesses.add(app);
2773            }
2774            nextIndex = mLruProcessServiceStart;
2775        } else if (hasService) {
2776            // Process has services, put it at the top of the service list.
2777            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2778            mLruProcesses.add(mLruProcessActivityStart, app);
2779            nextIndex = mLruProcessServiceStart;
2780            mLruProcessActivityStart++;
2781        } else  {
2782            // Process not otherwise of interest, it goes to the top of the non-service area.
2783            int index = mLruProcessServiceStart;
2784            if (client != null) {
2785                // If there is a client, don't allow the process to be moved up higher
2786                // in the list than that client.
2787                int clientIndex = mLruProcesses.lastIndexOf(client);
2788                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2789                        + " when updating " + app);
2790                if (clientIndex <= lrui) {
2791                    // Don't allow the client index restriction to push it down farther in the
2792                    // list than it already is.
2793                    clientIndex = lrui;
2794                }
2795                if (clientIndex >= 0 && index > clientIndex) {
2796                    index = clientIndex;
2797                }
2798            }
2799            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2800            mLruProcesses.add(index, app);
2801            nextIndex = index-1;
2802            mLruProcessActivityStart++;
2803            mLruProcessServiceStart++;
2804        }
2805
2806        // If the app is currently using a content provider or service,
2807        // bump those processes as well.
2808        for (int j=app.connections.size()-1; j>=0; j--) {
2809            ConnectionRecord cr = app.connections.valueAt(j);
2810            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2811                    && cr.binding.service.app != null
2812                    && cr.binding.service.app.lruSeq != mLruSeq
2813                    && !cr.binding.service.app.persistent) {
2814                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2815                        "service connection", cr, app);
2816            }
2817        }
2818        for (int j=app.conProviders.size()-1; j>=0; j--) {
2819            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2820            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2821                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2822                        "provider reference", cpr, app);
2823            }
2824        }
2825    }
2826
2827    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2828        if (uid == Process.SYSTEM_UID) {
2829            // The system gets to run in any process.  If there are multiple
2830            // processes with the same uid, just pick the first (this
2831            // should never happen).
2832            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2833            if (procs == null) return null;
2834            final int N = procs.size();
2835            for (int i = 0; i < N; i++) {
2836                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2837            }
2838        }
2839        ProcessRecord proc = mProcessNames.get(processName, uid);
2840        if (false && proc != null && !keepIfLarge
2841                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2842                && proc.lastCachedPss >= 4000) {
2843            // Turn this condition on to cause killing to happen regularly, for testing.
2844            if (proc.baseProcessTracker != null) {
2845                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2846            }
2847            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2848        } else if (proc != null && !keepIfLarge
2849                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2850                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2851            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2852            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2853                if (proc.baseProcessTracker != null) {
2854                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2855                }
2856                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2857            }
2858        }
2859        return proc;
2860    }
2861
2862    void ensurePackageDexOpt(String packageName) {
2863        IPackageManager pm = AppGlobals.getPackageManager();
2864        try {
2865            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2866                mDidDexOpt = true;
2867            }
2868        } catch (RemoteException e) {
2869        }
2870    }
2871
2872    boolean isNextTransitionForward() {
2873        int transit = mWindowManager.getPendingAppTransition();
2874        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2875                || transit == AppTransition.TRANSIT_TASK_OPEN
2876                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2877    }
2878
2879    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2880            String processName, String abiOverride, int uid, Runnable crashHandler) {
2881        synchronized(this) {
2882            ApplicationInfo info = new ApplicationInfo();
2883            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2884            // For isolated processes, the former contains the parent's uid and the latter the
2885            // actual uid of the isolated process.
2886            // In the special case introduced by this method (which is, starting an isolated
2887            // process directly from the SystemServer without an actual parent app process) the
2888            // closest thing to a parent's uid is SYSTEM_UID.
2889            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2890            // the |isolated| logic in the ProcessRecord constructor.
2891            info.uid = Process.SYSTEM_UID;
2892            info.processName = processName;
2893            info.className = entryPoint;
2894            info.packageName = "android";
2895            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2896                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2897                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2898                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2899                    crashHandler);
2900            return proc != null ? proc.pid : 0;
2901        }
2902    }
2903
2904    final ProcessRecord startProcessLocked(String processName,
2905            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2906            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2907            boolean isolated, boolean keepIfLarge) {
2908        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2909                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2910                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2911                null /* crashHandler */);
2912    }
2913
2914    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2915            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2916            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2917            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2918        long startTime = SystemClock.elapsedRealtime();
2919        ProcessRecord app;
2920        if (!isolated) {
2921            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2922            checkTime(startTime, "startProcess: after getProcessRecord");
2923        } else {
2924            // If this is an isolated process, it can't re-use an existing process.
2925            app = null;
2926        }
2927        // We don't have to do anything more if:
2928        // (1) There is an existing application record; and
2929        // (2) The caller doesn't think it is dead, OR there is no thread
2930        //     object attached to it so we know it couldn't have crashed; and
2931        // (3) There is a pid assigned to it, so it is either starting or
2932        //     already running.
2933        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2934                + " app=" + app + " knownToBeDead=" + knownToBeDead
2935                + " thread=" + (app != null ? app.thread : null)
2936                + " pid=" + (app != null ? app.pid : -1));
2937        if (app != null && app.pid > 0) {
2938            if (!knownToBeDead || app.thread == null) {
2939                // We already have the app running, or are waiting for it to
2940                // come up (we have a pid but not yet its thread), so keep it.
2941                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2942                // If this is a new package in the process, add the package to the list
2943                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2944                checkTime(startTime, "startProcess: done, added package to proc");
2945                return app;
2946            }
2947
2948            // An application record is attached to a previous process,
2949            // clean it up now.
2950            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2951            checkTime(startTime, "startProcess: bad proc running, killing");
2952            Process.killProcessGroup(app.info.uid, app.pid);
2953            handleAppDiedLocked(app, true, true);
2954            checkTime(startTime, "startProcess: done killing old proc");
2955        }
2956
2957        String hostingNameStr = hostingName != null
2958                ? hostingName.flattenToShortString() : null;
2959
2960        if (!isolated) {
2961            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2962                // If we are in the background, then check to see if this process
2963                // is bad.  If so, we will just silently fail.
2964                if (mBadProcesses.get(info.processName, info.uid) != null) {
2965                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2966                            + "/" + info.processName);
2967                    return null;
2968                }
2969            } else {
2970                // When the user is explicitly starting a process, then clear its
2971                // crash count so that we won't make it bad until they see at
2972                // least one crash dialog again, and make the process good again
2973                // if it had been bad.
2974                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2975                        + "/" + info.processName);
2976                mProcessCrashTimes.remove(info.processName, info.uid);
2977                if (mBadProcesses.get(info.processName, info.uid) != null) {
2978                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2979                            UserHandle.getUserId(info.uid), info.uid,
2980                            info.processName);
2981                    mBadProcesses.remove(info.processName, info.uid);
2982                    if (app != null) {
2983                        app.bad = false;
2984                    }
2985                }
2986            }
2987        }
2988
2989        if (app == null) {
2990            checkTime(startTime, "startProcess: creating new process record");
2991            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2992            app.crashHandler = crashHandler;
2993            if (app == null) {
2994                Slog.w(TAG, "Failed making new process record for "
2995                        + processName + "/" + info.uid + " isolated=" + isolated);
2996                return null;
2997            }
2998            mProcessNames.put(processName, app.uid, app);
2999            if (isolated) {
3000                mIsolatedProcesses.put(app.uid, app);
3001            }
3002            checkTime(startTime, "startProcess: done creating new process record");
3003        } else {
3004            // If this is a new package in the process, add the package to the list
3005            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3006            checkTime(startTime, "startProcess: added package to existing proc");
3007        }
3008
3009        // If the system is not ready yet, then hold off on starting this
3010        // process until it is.
3011        if (!mProcessesReady
3012                && !isAllowedWhileBooting(info)
3013                && !allowWhileBooting) {
3014            if (!mProcessesOnHold.contains(app)) {
3015                mProcessesOnHold.add(app);
3016            }
3017            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3018            checkTime(startTime, "startProcess: returning with proc on hold");
3019            return app;
3020        }
3021
3022        checkTime(startTime, "startProcess: stepping in to startProcess");
3023        startProcessLocked(
3024                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3025        checkTime(startTime, "startProcess: done starting proc!");
3026        return (app.pid != 0) ? app : null;
3027    }
3028
3029    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3030        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3031    }
3032
3033    private final void startProcessLocked(ProcessRecord app,
3034            String hostingType, String hostingNameStr) {
3035        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3036                null /* entryPoint */, null /* entryPointArgs */);
3037    }
3038
3039    private final void startProcessLocked(ProcessRecord app, String hostingType,
3040            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3041        long startTime = SystemClock.elapsedRealtime();
3042        if (app.pid > 0 && app.pid != MY_PID) {
3043            checkTime(startTime, "startProcess: removing from pids map");
3044            synchronized (mPidsSelfLocked) {
3045                mPidsSelfLocked.remove(app.pid);
3046                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3047            }
3048            checkTime(startTime, "startProcess: done removing from pids map");
3049            app.setPid(0);
3050        }
3051
3052        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3053                "startProcessLocked removing on hold: " + app);
3054        mProcessesOnHold.remove(app);
3055
3056        checkTime(startTime, "startProcess: starting to update cpu stats");
3057        updateCpuStats();
3058        checkTime(startTime, "startProcess: done updating cpu stats");
3059
3060        try {
3061            int uid = app.uid;
3062
3063            int[] gids = null;
3064            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3065            if (!app.isolated) {
3066                int[] permGids = null;
3067                try {
3068                    checkTime(startTime, "startProcess: getting gids from package manager");
3069                    final PackageManager pm = mContext.getPackageManager();
3070                    permGids = pm.getPackageGids(app.info.packageName);
3071
3072                    if (Environment.isExternalStorageEmulated()) {
3073                        checkTime(startTime, "startProcess: checking external storage perm");
3074                        if (pm.checkPermission(
3075                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3076                                app.info.packageName) == PERMISSION_GRANTED) {
3077                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3078                        } else {
3079                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3080                        }
3081                    }
3082                } catch (PackageManager.NameNotFoundException e) {
3083                    Slog.w(TAG, "Unable to retrieve gids", e);
3084                }
3085
3086                /*
3087                 * Add shared application and profile GIDs so applications can share some
3088                 * resources like shared libraries and access user-wide resources
3089                 */
3090                if (permGids == null) {
3091                    gids = new int[2];
3092                } else {
3093                    gids = new int[permGids.length + 2];
3094                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3095                }
3096                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3097                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3098            }
3099            checkTime(startTime, "startProcess: building args");
3100            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3101                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3102                        && mTopComponent != null
3103                        && app.processName.equals(mTopComponent.getPackageName())) {
3104                    uid = 0;
3105                }
3106                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3107                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3108                    uid = 0;
3109                }
3110            }
3111            int debugFlags = 0;
3112            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3113                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3114                // Also turn on CheckJNI for debuggable apps. It's quite
3115                // awkward to turn on otherwise.
3116                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3117            }
3118            // Run the app in safe mode if its manifest requests so or the
3119            // system is booted in safe mode.
3120            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3121                mSafeMode == true) {
3122                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3123            }
3124            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3125                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3126            }
3127            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3128                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3129            }
3130            if ("1".equals(SystemProperties.get("debug.assert"))) {
3131                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3132            }
3133
3134            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3135            if (requiredAbi == null) {
3136                requiredAbi = Build.SUPPORTED_ABIS[0];
3137            }
3138
3139            String instructionSet = null;
3140            if (app.info.primaryCpuAbi != null) {
3141                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3142            }
3143
3144            // Start the process.  It will either succeed and return a result containing
3145            // the PID of the new process, or else throw a RuntimeException.
3146            boolean isActivityProcess = (entryPoint == null);
3147            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3148            checkTime(startTime, "startProcess: asking zygote to start proc");
3149            Process.ProcessStartResult startResult = Process.start(entryPoint,
3150                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3151                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3152                    entryPointArgs);
3153            checkTime(startTime, "startProcess: returned from zygote!");
3154
3155            if (app.isolated) {
3156                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3157            }
3158            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3159            checkTime(startTime, "startProcess: done updating battery stats");
3160
3161            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3162                    UserHandle.getUserId(uid), startResult.pid, uid,
3163                    app.processName, hostingType,
3164                    hostingNameStr != null ? hostingNameStr : "");
3165
3166            if (app.persistent) {
3167                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3168            }
3169
3170            checkTime(startTime, "startProcess: building log message");
3171            StringBuilder buf = mStringBuilder;
3172            buf.setLength(0);
3173            buf.append("Start proc ");
3174            buf.append(app.processName);
3175            if (!isActivityProcess) {
3176                buf.append(" [");
3177                buf.append(entryPoint);
3178                buf.append("]");
3179            }
3180            buf.append(" for ");
3181            buf.append(hostingType);
3182            if (hostingNameStr != null) {
3183                buf.append(" ");
3184                buf.append(hostingNameStr);
3185            }
3186            buf.append(": pid=");
3187            buf.append(startResult.pid);
3188            buf.append(" uid=");
3189            buf.append(uid);
3190            buf.append(" gids={");
3191            if (gids != null) {
3192                for (int gi=0; gi<gids.length; gi++) {
3193                    if (gi != 0) buf.append(", ");
3194                    buf.append(gids[gi]);
3195
3196                }
3197            }
3198            buf.append("}");
3199            if (requiredAbi != null) {
3200                buf.append(" abi=");
3201                buf.append(requiredAbi);
3202            }
3203            Slog.i(TAG, buf.toString());
3204            app.setPid(startResult.pid);
3205            app.usingWrapper = startResult.usingWrapper;
3206            app.removed = false;
3207            app.killed = false;
3208            app.killedByAm = false;
3209            checkTime(startTime, "startProcess: starting to update pids map");
3210            synchronized (mPidsSelfLocked) {
3211                this.mPidsSelfLocked.put(startResult.pid, app);
3212                if (isActivityProcess) {
3213                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3214                    msg.obj = app;
3215                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3216                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3217                }
3218            }
3219            checkTime(startTime, "startProcess: done updating pids map");
3220        } catch (RuntimeException e) {
3221            // XXX do better error recovery.
3222            app.setPid(0);
3223            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3224            if (app.isolated) {
3225                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3226            }
3227            Slog.e(TAG, "Failure starting process " + app.processName, e);
3228        }
3229    }
3230
3231    void updateUsageStats(ActivityRecord component, boolean resumed) {
3232        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3233        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3234        if (resumed) {
3235            if (mUsageStatsService != null) {
3236                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3237                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3238            }
3239            synchronized (stats) {
3240                stats.noteActivityResumedLocked(component.app.uid);
3241            }
3242        } else {
3243            if (mUsageStatsService != null) {
3244                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3245                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3246            }
3247            synchronized (stats) {
3248                stats.noteActivityPausedLocked(component.app.uid);
3249            }
3250        }
3251    }
3252
3253    Intent getHomeIntent() {
3254        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3255        intent.setComponent(mTopComponent);
3256        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3257            intent.addCategory(Intent.CATEGORY_HOME);
3258        }
3259        return intent;
3260    }
3261
3262    boolean startHomeActivityLocked(int userId) {
3263        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3264                && mTopAction == null) {
3265            // We are running in factory test mode, but unable to find
3266            // the factory test app, so just sit around displaying the
3267            // error message and don't try to start anything.
3268            return false;
3269        }
3270        Intent intent = getHomeIntent();
3271        ActivityInfo aInfo =
3272            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3273        if (aInfo != null) {
3274            intent.setComponent(new ComponentName(
3275                    aInfo.applicationInfo.packageName, aInfo.name));
3276            // Don't do this if the home app is currently being
3277            // instrumented.
3278            aInfo = new ActivityInfo(aInfo);
3279            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3280            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3281                    aInfo.applicationInfo.uid, true);
3282            if (app == null || app.instrumentationClass == null) {
3283                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3284                mStackSupervisor.startHomeActivity(intent, aInfo);
3285            }
3286        }
3287
3288        return true;
3289    }
3290
3291    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3292        ActivityInfo ai = null;
3293        ComponentName comp = intent.getComponent();
3294        try {
3295            if (comp != null) {
3296                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3297            } else {
3298                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3299                        intent,
3300                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3301                            flags, userId);
3302
3303                if (info != null) {
3304                    ai = info.activityInfo;
3305                }
3306            }
3307        } catch (RemoteException e) {
3308            // ignore
3309        }
3310
3311        return ai;
3312    }
3313
3314    /**
3315     * Starts the "new version setup screen" if appropriate.
3316     */
3317    void startSetupActivityLocked() {
3318        // Only do this once per boot.
3319        if (mCheckedForSetup) {
3320            return;
3321        }
3322
3323        // We will show this screen if the current one is a different
3324        // version than the last one shown, and we are not running in
3325        // low-level factory test mode.
3326        final ContentResolver resolver = mContext.getContentResolver();
3327        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3328                Settings.Global.getInt(resolver,
3329                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3330            mCheckedForSetup = true;
3331
3332            // See if we should be showing the platform update setup UI.
3333            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3334            List<ResolveInfo> ris = mContext.getPackageManager()
3335                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3336
3337            // We don't allow third party apps to replace this.
3338            ResolveInfo ri = null;
3339            for (int i=0; ris != null && i<ris.size(); i++) {
3340                if ((ris.get(i).activityInfo.applicationInfo.flags
3341                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3342                    ri = ris.get(i);
3343                    break;
3344                }
3345            }
3346
3347            if (ri != null) {
3348                String vers = ri.activityInfo.metaData != null
3349                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3350                        : null;
3351                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3352                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3353                            Intent.METADATA_SETUP_VERSION);
3354                }
3355                String lastVers = Settings.Secure.getString(
3356                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3357                if (vers != null && !vers.equals(lastVers)) {
3358                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3359                    intent.setComponent(new ComponentName(
3360                            ri.activityInfo.packageName, ri.activityInfo.name));
3361                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3362                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3363                            null);
3364                }
3365            }
3366        }
3367    }
3368
3369    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3370        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3371    }
3372
3373    void enforceNotIsolatedCaller(String caller) {
3374        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3375            throw new SecurityException("Isolated process not allowed to call " + caller);
3376        }
3377    }
3378
3379    void enforceShellRestriction(String restriction, int userHandle) {
3380        if (Binder.getCallingUid() == Process.SHELL_UID) {
3381            if (userHandle < 0
3382                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3383                throw new SecurityException("Shell does not have permission to access user "
3384                        + userHandle);
3385            }
3386        }
3387    }
3388
3389    @Override
3390    public int getFrontActivityScreenCompatMode() {
3391        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3392        synchronized (this) {
3393            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3394        }
3395    }
3396
3397    @Override
3398    public void setFrontActivityScreenCompatMode(int mode) {
3399        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3400                "setFrontActivityScreenCompatMode");
3401        synchronized (this) {
3402            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3403        }
3404    }
3405
3406    @Override
3407    public int getPackageScreenCompatMode(String packageName) {
3408        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3409        synchronized (this) {
3410            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3411        }
3412    }
3413
3414    @Override
3415    public void setPackageScreenCompatMode(String packageName, int mode) {
3416        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3417                "setPackageScreenCompatMode");
3418        synchronized (this) {
3419            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3420        }
3421    }
3422
3423    @Override
3424    public boolean getPackageAskScreenCompat(String packageName) {
3425        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3426        synchronized (this) {
3427            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3428        }
3429    }
3430
3431    @Override
3432    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3433        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3434                "setPackageAskScreenCompat");
3435        synchronized (this) {
3436            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3437        }
3438    }
3439
3440    private void dispatchProcessesChanged() {
3441        int N;
3442        synchronized (this) {
3443            N = mPendingProcessChanges.size();
3444            if (mActiveProcessChanges.length < N) {
3445                mActiveProcessChanges = new ProcessChangeItem[N];
3446            }
3447            mPendingProcessChanges.toArray(mActiveProcessChanges);
3448            mAvailProcessChanges.addAll(mPendingProcessChanges);
3449            mPendingProcessChanges.clear();
3450            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3451        }
3452
3453        int i = mProcessObservers.beginBroadcast();
3454        while (i > 0) {
3455            i--;
3456            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3457            if (observer != null) {
3458                try {
3459                    for (int j=0; j<N; j++) {
3460                        ProcessChangeItem item = mActiveProcessChanges[j];
3461                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3462                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3463                                    + item.pid + " uid=" + item.uid + ": "
3464                                    + item.foregroundActivities);
3465                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3466                                    item.foregroundActivities);
3467                        }
3468                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3469                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3470                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3471                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3472                        }
3473                    }
3474                } catch (RemoteException e) {
3475                }
3476            }
3477        }
3478        mProcessObservers.finishBroadcast();
3479    }
3480
3481    private void dispatchProcessDied(int pid, int uid) {
3482        int i = mProcessObservers.beginBroadcast();
3483        while (i > 0) {
3484            i--;
3485            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3486            if (observer != null) {
3487                try {
3488                    observer.onProcessDied(pid, uid);
3489                } catch (RemoteException e) {
3490                }
3491            }
3492        }
3493        mProcessObservers.finishBroadcast();
3494    }
3495
3496    @Override
3497    public final int startActivity(IApplicationThread caller, String callingPackage,
3498            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3499            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3500        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3501            resultWho, requestCode, startFlags, profilerInfo, options,
3502            UserHandle.getCallingUserId());
3503    }
3504
3505    @Override
3506    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3507            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3508            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3509        enforceNotIsolatedCaller("startActivity");
3510        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3511                false, ALLOW_FULL_ONLY, "startActivity", null);
3512        // TODO: Switch to user app stacks here.
3513        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3514                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3515                profilerInfo, null, null, options, userId, null, null);
3516    }
3517
3518    @Override
3519    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3520            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3521            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3522
3523        // This is very dangerous -- it allows you to perform a start activity (including
3524        // permission grants) as any app that may launch one of your own activities.  So
3525        // we will only allow this to be done from activities that are part of the core framework,
3526        // and then only when they are running as the system.
3527        final ActivityRecord sourceRecord;
3528        final int targetUid;
3529        final String targetPackage;
3530        synchronized (this) {
3531            if (resultTo == null) {
3532                throw new SecurityException("Must be called from an activity");
3533            }
3534            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3535            if (sourceRecord == null) {
3536                throw new SecurityException("Called with bad activity token: " + resultTo);
3537            }
3538            if (!sourceRecord.info.packageName.equals("android")) {
3539                throw new SecurityException(
3540                        "Must be called from an activity that is declared in the android package");
3541            }
3542            if (sourceRecord.app == null) {
3543                throw new SecurityException("Called without a process attached to activity");
3544            }
3545            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3546                // This is still okay, as long as this activity is running under the
3547                // uid of the original calling activity.
3548                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3549                    throw new SecurityException(
3550                            "Calling activity in uid " + sourceRecord.app.uid
3551                                    + " must be system uid or original calling uid "
3552                                    + sourceRecord.launchedFromUid);
3553                }
3554            }
3555            targetUid = sourceRecord.launchedFromUid;
3556            targetPackage = sourceRecord.launchedFromPackage;
3557        }
3558
3559        // TODO: Switch to user app stacks here.
3560        try {
3561            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3562                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3563                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3564            return ret;
3565        } catch (SecurityException e) {
3566            // XXX need to figure out how to propagate to original app.
3567            // A SecurityException here is generally actually a fault of the original
3568            // calling activity (such as a fairly granting permissions), so propagate it
3569            // back to them.
3570            /*
3571            StringBuilder msg = new StringBuilder();
3572            msg.append("While launching");
3573            msg.append(intent.toString());
3574            msg.append(": ");
3575            msg.append(e.getMessage());
3576            */
3577            throw e;
3578        }
3579    }
3580
3581    @Override
3582    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3583            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3584            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3585        enforceNotIsolatedCaller("startActivityAndWait");
3586        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3587                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3588        WaitResult res = new WaitResult();
3589        // TODO: Switch to user app stacks here.
3590        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3591                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3592                options, userId, null, null);
3593        return res;
3594    }
3595
3596    @Override
3597    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3598            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3599            int startFlags, Configuration config, Bundle options, int userId) {
3600        enforceNotIsolatedCaller("startActivityWithConfig");
3601        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3602                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3603        // TODO: Switch to user app stacks here.
3604        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3605                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3606                null, null, config, options, userId, null, null);
3607        return ret;
3608    }
3609
3610    @Override
3611    public int startActivityIntentSender(IApplicationThread caller,
3612            IntentSender intent, Intent fillInIntent, String resolvedType,
3613            IBinder resultTo, String resultWho, int requestCode,
3614            int flagsMask, int flagsValues, Bundle options) {
3615        enforceNotIsolatedCaller("startActivityIntentSender");
3616        // Refuse possible leaked file descriptors
3617        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3618            throw new IllegalArgumentException("File descriptors passed in Intent");
3619        }
3620
3621        IIntentSender sender = intent.getTarget();
3622        if (!(sender instanceof PendingIntentRecord)) {
3623            throw new IllegalArgumentException("Bad PendingIntent object");
3624        }
3625
3626        PendingIntentRecord pir = (PendingIntentRecord)sender;
3627
3628        synchronized (this) {
3629            // If this is coming from the currently resumed activity, it is
3630            // effectively saying that app switches are allowed at this point.
3631            final ActivityStack stack = getFocusedStack();
3632            if (stack.mResumedActivity != null &&
3633                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3634                mAppSwitchesAllowedTime = 0;
3635            }
3636        }
3637        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3638                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3639        return ret;
3640    }
3641
3642    @Override
3643    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3644            Intent intent, String resolvedType, IVoiceInteractionSession session,
3645            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3646            Bundle options, int userId) {
3647        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3648                != PackageManager.PERMISSION_GRANTED) {
3649            String msg = "Permission Denial: startVoiceActivity() from pid="
3650                    + Binder.getCallingPid()
3651                    + ", uid=" + Binder.getCallingUid()
3652                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3653            Slog.w(TAG, msg);
3654            throw new SecurityException(msg);
3655        }
3656        if (session == null || interactor == null) {
3657            throw new NullPointerException("null session or interactor");
3658        }
3659        userId = handleIncomingUser(callingPid, callingUid, userId,
3660                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3661        // TODO: Switch to user app stacks here.
3662        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3663                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3664                null, options, userId, null, null);
3665    }
3666
3667    @Override
3668    public boolean startNextMatchingActivity(IBinder callingActivity,
3669            Intent intent, Bundle options) {
3670        // Refuse possible leaked file descriptors
3671        if (intent != null && intent.hasFileDescriptors() == true) {
3672            throw new IllegalArgumentException("File descriptors passed in Intent");
3673        }
3674
3675        synchronized (this) {
3676            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3677            if (r == null) {
3678                ActivityOptions.abort(options);
3679                return false;
3680            }
3681            if (r.app == null || r.app.thread == null) {
3682                // The caller is not running...  d'oh!
3683                ActivityOptions.abort(options);
3684                return false;
3685            }
3686            intent = new Intent(intent);
3687            // The caller is not allowed to change the data.
3688            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3689            // And we are resetting to find the next component...
3690            intent.setComponent(null);
3691
3692            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3693
3694            ActivityInfo aInfo = null;
3695            try {
3696                List<ResolveInfo> resolves =
3697                    AppGlobals.getPackageManager().queryIntentActivities(
3698                            intent, r.resolvedType,
3699                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3700                            UserHandle.getCallingUserId());
3701
3702                // Look for the original activity in the list...
3703                final int N = resolves != null ? resolves.size() : 0;
3704                for (int i=0; i<N; i++) {
3705                    ResolveInfo rInfo = resolves.get(i);
3706                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3707                            && rInfo.activityInfo.name.equals(r.info.name)) {
3708                        // We found the current one...  the next matching is
3709                        // after it.
3710                        i++;
3711                        if (i<N) {
3712                            aInfo = resolves.get(i).activityInfo;
3713                        }
3714                        if (debug) {
3715                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3716                                    + "/" + r.info.name);
3717                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3718                                    + "/" + aInfo.name);
3719                        }
3720                        break;
3721                    }
3722                }
3723            } catch (RemoteException e) {
3724            }
3725
3726            if (aInfo == null) {
3727                // Nobody who is next!
3728                ActivityOptions.abort(options);
3729                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3730                return false;
3731            }
3732
3733            intent.setComponent(new ComponentName(
3734                    aInfo.applicationInfo.packageName, aInfo.name));
3735            intent.setFlags(intent.getFlags()&~(
3736                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3737                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3738                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3739                    Intent.FLAG_ACTIVITY_NEW_TASK));
3740
3741            // Okay now we need to start the new activity, replacing the
3742            // currently running activity.  This is a little tricky because
3743            // we want to start the new one as if the current one is finished,
3744            // but not finish the current one first so that there is no flicker.
3745            // And thus...
3746            final boolean wasFinishing = r.finishing;
3747            r.finishing = true;
3748
3749            // Propagate reply information over to the new activity.
3750            final ActivityRecord resultTo = r.resultTo;
3751            final String resultWho = r.resultWho;
3752            final int requestCode = r.requestCode;
3753            r.resultTo = null;
3754            if (resultTo != null) {
3755                resultTo.removeResultsLocked(r, resultWho, requestCode);
3756            }
3757
3758            final long origId = Binder.clearCallingIdentity();
3759            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3760                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3761                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3762                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3763            Binder.restoreCallingIdentity(origId);
3764
3765            r.finishing = wasFinishing;
3766            if (res != ActivityManager.START_SUCCESS) {
3767                return false;
3768            }
3769            return true;
3770        }
3771    }
3772
3773    @Override
3774    public final int startActivityFromRecents(int taskId, Bundle options) {
3775        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3776            String msg = "Permission Denial: startActivityFromRecents called without " +
3777                    START_TASKS_FROM_RECENTS;
3778            Slog.w(TAG, msg);
3779            throw new SecurityException(msg);
3780        }
3781        return startActivityFromRecentsInner(taskId, options);
3782    }
3783
3784    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3785        final TaskRecord task;
3786        final int callingUid;
3787        final String callingPackage;
3788        final Intent intent;
3789        final int userId;
3790        synchronized (this) {
3791            task = recentTaskForIdLocked(taskId);
3792            if (task == null) {
3793                throw new IllegalArgumentException("Task " + taskId + " not found.");
3794            }
3795            callingUid = task.mCallingUid;
3796            callingPackage = task.mCallingPackage;
3797            intent = task.intent;
3798            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3799            userId = task.userId;
3800        }
3801        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3802                options, userId, null, task);
3803    }
3804
3805    final int startActivityInPackage(int uid, String callingPackage,
3806            Intent intent, String resolvedType, IBinder resultTo,
3807            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3808            IActivityContainer container, TaskRecord inTask) {
3809
3810        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3811                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3812
3813        // TODO: Switch to user app stacks here.
3814        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3815                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3816                null, null, null, options, userId, container, inTask);
3817        return ret;
3818    }
3819
3820    @Override
3821    public final int startActivities(IApplicationThread caller, String callingPackage,
3822            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3823            int userId) {
3824        enforceNotIsolatedCaller("startActivities");
3825        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3826                false, ALLOW_FULL_ONLY, "startActivity", null);
3827        // TODO: Switch to user app stacks here.
3828        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3829                resolvedTypes, resultTo, options, userId);
3830        return ret;
3831    }
3832
3833    final int startActivitiesInPackage(int uid, String callingPackage,
3834            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3835            Bundle options, int userId) {
3836
3837        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3838                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3839        // TODO: Switch to user app stacks here.
3840        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3841                resultTo, options, userId);
3842        return ret;
3843    }
3844
3845    //explicitly remove thd old information in mRecentTasks when removing existing user.
3846    private void removeRecentTasksForUserLocked(int userId) {
3847        if(userId <= 0) {
3848            Slog.i(TAG, "Can't remove recent task on user " + userId);
3849            return;
3850        }
3851
3852        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3853            TaskRecord tr = mRecentTasks.get(i);
3854            if (tr.userId == userId) {
3855                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3856                        + " when finishing user" + userId);
3857                mRecentTasks.remove(i);
3858                tr.removedFromRecents(mTaskPersister);
3859            }
3860        }
3861
3862        // Remove tasks from persistent storage.
3863        mTaskPersister.wakeup(null, true);
3864    }
3865
3866    // Sort by taskId
3867    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3868        @Override
3869        public int compare(TaskRecord lhs, TaskRecord rhs) {
3870            return rhs.taskId - lhs.taskId;
3871        }
3872    };
3873
3874    // Extract the affiliates of the chain containing mRecentTasks[start].
3875    private int processNextAffiliateChain(int start) {
3876        final TaskRecord startTask = mRecentTasks.get(start);
3877        final int affiliateId = startTask.mAffiliatedTaskId;
3878
3879        // Quick identification of isolated tasks. I.e. those not launched behind.
3880        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3881                startTask.mNextAffiliate == null) {
3882            // There is still a slim chance that there are other tasks that point to this task
3883            // and that the chain is so messed up that this task no longer points to them but
3884            // the gain of this optimization outweighs the risk.
3885            startTask.inRecents = true;
3886            return start + 1;
3887        }
3888
3889        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3890        mTmpRecents.clear();
3891        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3892            final TaskRecord task = mRecentTasks.get(i);
3893            if (task.mAffiliatedTaskId == affiliateId) {
3894                mRecentTasks.remove(i);
3895                mTmpRecents.add(task);
3896            }
3897        }
3898
3899        // Sort them all by taskId. That is the order they were create in and that order will
3900        // always be correct.
3901        Collections.sort(mTmpRecents, mTaskRecordComparator);
3902
3903        // Go through and fix up the linked list.
3904        // The first one is the end of the chain and has no next.
3905        final TaskRecord first = mTmpRecents.get(0);
3906        first.inRecents = true;
3907        if (first.mNextAffiliate != null) {
3908            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3909            first.setNextAffiliate(null);
3910            mTaskPersister.wakeup(first, false);
3911        }
3912        // Everything in the middle is doubly linked from next to prev.
3913        final int tmpSize = mTmpRecents.size();
3914        for (int i = 0; i < tmpSize - 1; ++i) {
3915            final TaskRecord next = mTmpRecents.get(i);
3916            final TaskRecord prev = mTmpRecents.get(i + 1);
3917            if (next.mPrevAffiliate != prev) {
3918                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3919                        " setting prev=" + prev);
3920                next.setPrevAffiliate(prev);
3921                mTaskPersister.wakeup(next, false);
3922            }
3923            if (prev.mNextAffiliate != next) {
3924                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3925                        " setting next=" + next);
3926                prev.setNextAffiliate(next);
3927                mTaskPersister.wakeup(prev, false);
3928            }
3929            prev.inRecents = true;
3930        }
3931        // The last one is the beginning of the list and has no prev.
3932        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3933        if (last.mPrevAffiliate != null) {
3934            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3935            last.setPrevAffiliate(null);
3936            mTaskPersister.wakeup(last, false);
3937        }
3938
3939        // Insert the group back into mRecentTasks at start.
3940        mRecentTasks.addAll(start, mTmpRecents);
3941
3942        // Let the caller know where we left off.
3943        return start + tmpSize;
3944    }
3945
3946    /**
3947     * Update the recent tasks lists: make sure tasks should still be here (their
3948     * applications / activities still exist), update their availability, fixup ordering
3949     * of affiliations.
3950     */
3951    void cleanupRecentTasksLocked(int userId) {
3952        if (mRecentTasks == null) {
3953            // Happens when called from the packagemanager broadcast before boot.
3954            return;
3955        }
3956
3957        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3958        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3959        final IPackageManager pm = AppGlobals.getPackageManager();
3960        final ActivityInfo dummyAct = new ActivityInfo();
3961        final ApplicationInfo dummyApp = new ApplicationInfo();
3962
3963        int N = mRecentTasks.size();
3964
3965        int[] users = userId == UserHandle.USER_ALL
3966                ? getUsersLocked() : new int[] { userId };
3967        for (int user : users) {
3968            for (int i = 0; i < N; i++) {
3969                TaskRecord task = mRecentTasks.get(i);
3970                if (task.userId != user) {
3971                    // Only look at tasks for the user ID of interest.
3972                    continue;
3973                }
3974                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3975                    // This situation is broken, and we should just get rid of it now.
3976                    mRecentTasks.remove(i);
3977                    task.removedFromRecents(mTaskPersister);
3978                    i--;
3979                    N--;
3980                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3981                    continue;
3982                }
3983                // Check whether this activity is currently available.
3984                if (task.realActivity != null) {
3985                    ActivityInfo ai = availActCache.get(task.realActivity);
3986                    if (ai == null) {
3987                        try {
3988                            ai = pm.getActivityInfo(task.realActivity,
3989                                    PackageManager.GET_UNINSTALLED_PACKAGES
3990                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3991                        } catch (RemoteException e) {
3992                            // Will never happen.
3993                            continue;
3994                        }
3995                        if (ai == null) {
3996                            ai = dummyAct;
3997                        }
3998                        availActCache.put(task.realActivity, ai);
3999                    }
4000                    if (ai == dummyAct) {
4001                        // This could be either because the activity no longer exists, or the
4002                        // app is temporarily gone.  For the former we want to remove the recents
4003                        // entry; for the latter we want to mark it as unavailable.
4004                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4005                        if (app == null) {
4006                            try {
4007                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4008                                        PackageManager.GET_UNINSTALLED_PACKAGES
4009                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4010                            } catch (RemoteException e) {
4011                                // Will never happen.
4012                                continue;
4013                            }
4014                            if (app == null) {
4015                                app = dummyApp;
4016                            }
4017                            availAppCache.put(task.realActivity.getPackageName(), app);
4018                        }
4019                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4020                            // Doesn't exist any more!  Good-bye.
4021                            mRecentTasks.remove(i);
4022                            task.removedFromRecents(mTaskPersister);
4023                            i--;
4024                            N--;
4025                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4026                            continue;
4027                        } else {
4028                            // Otherwise just not available for now.
4029                            if (task.isAvailable) {
4030                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4031                                        + task);
4032                            }
4033                            task.isAvailable = false;
4034                        }
4035                    } else {
4036                        if (!ai.enabled || !ai.applicationInfo.enabled
4037                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4038                            if (task.isAvailable) {
4039                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4040                                        + task + " (enabled=" + ai.enabled + "/"
4041                                        + ai.applicationInfo.enabled +  " flags="
4042                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4043                            }
4044                            task.isAvailable = false;
4045                        } else {
4046                            if (!task.isAvailable) {
4047                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4048                                        + task);
4049                            }
4050                            task.isAvailable = true;
4051                        }
4052                    }
4053                }
4054            }
4055        }
4056
4057        // Verify the affiliate chain for each task.
4058        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4059        }
4060
4061        mTmpRecents.clear();
4062        // mRecentTasks is now in sorted, affiliated order.
4063    }
4064
4065    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4066        int N = mRecentTasks.size();
4067        TaskRecord top = task;
4068        int topIndex = taskIndex;
4069        while (top.mNextAffiliate != null && topIndex > 0) {
4070            top = top.mNextAffiliate;
4071            topIndex--;
4072        }
4073        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4074                + topIndex + " from intial " + taskIndex);
4075        // Find the end of the chain, doing a sanity check along the way.
4076        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4077        int endIndex = topIndex;
4078        TaskRecord prev = top;
4079        while (endIndex < N) {
4080            TaskRecord cur = mRecentTasks.get(endIndex);
4081            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4082                    + endIndex + " " + cur);
4083            if (cur == top) {
4084                // Verify start of the chain.
4085                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4086                    Slog.wtf(TAG, "Bad chain @" + endIndex
4087                            + ": first task has next affiliate: " + prev);
4088                    sane = false;
4089                    break;
4090                }
4091            } else {
4092                // Verify middle of the chain's next points back to the one before.
4093                if (cur.mNextAffiliate != prev
4094                        || cur.mNextAffiliateTaskId != prev.taskId) {
4095                    Slog.wtf(TAG, "Bad chain @" + endIndex
4096                            + ": middle task " + cur + " @" + endIndex
4097                            + " has bad next affiliate "
4098                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4099                            + ", expected " + prev);
4100                    sane = false;
4101                    break;
4102                }
4103            }
4104            if (cur.mPrevAffiliateTaskId == -1) {
4105                // Chain ends here.
4106                if (cur.mPrevAffiliate != null) {
4107                    Slog.wtf(TAG, "Bad chain @" + endIndex
4108                            + ": last task " + cur + " has previous affiliate "
4109                            + cur.mPrevAffiliate);
4110                    sane = false;
4111                }
4112                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4113                break;
4114            } else {
4115                // Verify middle of the chain's prev points to a valid item.
4116                if (cur.mPrevAffiliate == null) {
4117                    Slog.wtf(TAG, "Bad chain @" + endIndex
4118                            + ": task " + cur + " has previous affiliate "
4119                            + cur.mPrevAffiliate + " but should be id "
4120                            + cur.mPrevAffiliate);
4121                    sane = false;
4122                    break;
4123                }
4124            }
4125            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4126                Slog.wtf(TAG, "Bad chain @" + endIndex
4127                        + ": task " + cur + " has affiliated id "
4128                        + cur.mAffiliatedTaskId + " but should be "
4129                        + task.mAffiliatedTaskId);
4130                sane = false;
4131                break;
4132            }
4133            prev = cur;
4134            endIndex++;
4135            if (endIndex >= N) {
4136                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4137                        + ": last task " + prev);
4138                sane = false;
4139                break;
4140            }
4141        }
4142        if (sane) {
4143            if (endIndex < taskIndex) {
4144                Slog.wtf(TAG, "Bad chain @" + endIndex
4145                        + ": did not extend to task " + task + " @" + taskIndex);
4146                sane = false;
4147            }
4148        }
4149        if (sane) {
4150            // All looks good, we can just move all of the affiliated tasks
4151            // to the top.
4152            for (int i=topIndex; i<=endIndex; i++) {
4153                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4154                        + " from " + i + " to " + (i-topIndex));
4155                TaskRecord cur = mRecentTasks.remove(i);
4156                mRecentTasks.add(i-topIndex, cur);
4157            }
4158            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4159                    + " to " + endIndex);
4160            return true;
4161        }
4162
4163        // Whoops, couldn't do it.
4164        return false;
4165    }
4166
4167    final void addRecentTaskLocked(TaskRecord task) {
4168        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4169                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4170
4171        int N = mRecentTasks.size();
4172        // Quick case: check if the top-most recent task is the same.
4173        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4174            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4175            return;
4176        }
4177        // Another quick case: check if this is part of a set of affiliated
4178        // tasks that are at the top.
4179        if (isAffiliated && N > 0 && task.inRecents
4180                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4181            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4182                    + " at top when adding " + task);
4183            return;
4184        }
4185        // Another quick case: never add voice sessions.
4186        if (task.voiceSession != null) {
4187            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4188            return;
4189        }
4190
4191        boolean needAffiliationFix = false;
4192
4193        // Slightly less quick case: the task is already in recents, so all we need
4194        // to do is move it.
4195        if (task.inRecents) {
4196            int taskIndex = mRecentTasks.indexOf(task);
4197            if (taskIndex >= 0) {
4198                if (!isAffiliated) {
4199                    // Simple case: this is not an affiliated task, so we just move it to the front.
4200                    mRecentTasks.remove(taskIndex);
4201                    mRecentTasks.add(0, task);
4202                    notifyTaskPersisterLocked(task, false);
4203                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4204                            + " from " + taskIndex);
4205                    return;
4206                } else {
4207                    // More complicated: need to keep all affiliated tasks together.
4208                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4209                        // All went well.
4210                        return;
4211                    }
4212
4213                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4214                    // everything and then go through our general path of adding a new task.
4215                    needAffiliationFix = true;
4216                }
4217            } else {
4218                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4219                needAffiliationFix = true;
4220            }
4221        }
4222
4223        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4224        trimRecentsForTask(task, true);
4225
4226        N = mRecentTasks.size();
4227        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4228            final TaskRecord tr = mRecentTasks.remove(N - 1);
4229            tr.removedFromRecents(mTaskPersister);
4230            N--;
4231        }
4232        task.inRecents = true;
4233        if (!isAffiliated || needAffiliationFix) {
4234            // If this is a simple non-affiliated task, or we had some failure trying to
4235            // handle it as part of an affilated task, then just place it at the top.
4236            mRecentTasks.add(0, task);
4237        } else if (isAffiliated) {
4238            // If this is a new affiliated task, then move all of the affiliated tasks
4239            // to the front and insert this new one.
4240            TaskRecord other = task.mNextAffiliate;
4241            if (other == null) {
4242                other = task.mPrevAffiliate;
4243            }
4244            if (other != null) {
4245                int otherIndex = mRecentTasks.indexOf(other);
4246                if (otherIndex >= 0) {
4247                    // Insert new task at appropriate location.
4248                    int taskIndex;
4249                    if (other == task.mNextAffiliate) {
4250                        // We found the index of our next affiliation, which is who is
4251                        // before us in the list, so add after that point.
4252                        taskIndex = otherIndex+1;
4253                    } else {
4254                        // We found the index of our previous affiliation, which is who is
4255                        // after us in the list, so add at their position.
4256                        taskIndex = otherIndex;
4257                    }
4258                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4259                            + taskIndex + ": " + task);
4260                    mRecentTasks.add(taskIndex, task);
4261
4262                    // Now move everything to the front.
4263                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4264                        // All went well.
4265                        return;
4266                    }
4267
4268                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4269                    // everything and then go through our general path of adding a new task.
4270                    needAffiliationFix = true;
4271                } else {
4272                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4273                            + other);
4274                    needAffiliationFix = true;
4275                }
4276            } else {
4277                if (DEBUG_RECENTS) Slog.d(TAG,
4278                        "addRecent: adding affiliated task without next/prev:" + task);
4279                needAffiliationFix = true;
4280            }
4281        }
4282        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4283
4284        if (needAffiliationFix) {
4285            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4286            cleanupRecentTasksLocked(task.userId);
4287        }
4288    }
4289
4290    /**
4291     * If needed, remove oldest existing entries in recents that are for the same kind
4292     * of task as the given one.
4293     */
4294    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4295        int N = mRecentTasks.size();
4296        final Intent intent = task.intent;
4297        final boolean document = intent != null && intent.isDocument();
4298
4299        int maxRecents = task.maxRecents - 1;
4300        for (int i=0; i<N; i++) {
4301            final TaskRecord tr = mRecentTasks.get(i);
4302            if (task != tr) {
4303                if (task.userId != tr.userId) {
4304                    continue;
4305                }
4306                if (i > MAX_RECENT_BITMAPS) {
4307                    tr.freeLastThumbnail();
4308                }
4309                final Intent trIntent = tr.intent;
4310                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4311                    (intent == null || !intent.filterEquals(trIntent))) {
4312                    continue;
4313                }
4314                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4315                if (document && trIsDocument) {
4316                    // These are the same document activity (not necessarily the same doc).
4317                    if (maxRecents > 0) {
4318                        --maxRecents;
4319                        continue;
4320                    }
4321                    // Hit the maximum number of documents for this task. Fall through
4322                    // and remove this document from recents.
4323                } else if (document || trIsDocument) {
4324                    // Only one of these is a document. Not the droid we're looking for.
4325                    continue;
4326                }
4327            }
4328
4329            if (!doTrim) {
4330                // If the caller is not actually asking for a trim, just tell them we reached
4331                // a point where the trim would happen.
4332                return i;
4333            }
4334
4335            // Either task and tr are the same or, their affinities match or their intents match
4336            // and neither of them is a document, or they are documents using the same activity
4337            // and their maxRecents has been reached.
4338            tr.disposeThumbnail();
4339            mRecentTasks.remove(i);
4340            if (task != tr) {
4341                tr.removedFromRecents(mTaskPersister);
4342            }
4343            i--;
4344            N--;
4345            if (task.intent == null) {
4346                // If the new recent task we are adding is not fully
4347                // specified, then replace it with the existing recent task.
4348                task = tr;
4349            }
4350            notifyTaskPersisterLocked(tr, false);
4351        }
4352
4353        return -1;
4354    }
4355
4356    @Override
4357    public void reportActivityFullyDrawn(IBinder token) {
4358        synchronized (this) {
4359            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4360            if (r == null) {
4361                return;
4362            }
4363            r.reportFullyDrawnLocked();
4364        }
4365    }
4366
4367    @Override
4368    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4369        synchronized (this) {
4370            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4371            if (r == null) {
4372                return;
4373            }
4374            final long origId = Binder.clearCallingIdentity();
4375            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4376            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4377                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4378            if (config != null) {
4379                r.frozenBeforeDestroy = true;
4380                if (!updateConfigurationLocked(config, r, false, false)) {
4381                    mStackSupervisor.resumeTopActivitiesLocked();
4382                }
4383            }
4384            Binder.restoreCallingIdentity(origId);
4385        }
4386    }
4387
4388    @Override
4389    public int getRequestedOrientation(IBinder token) {
4390        synchronized (this) {
4391            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4392            if (r == null) {
4393                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4394            }
4395            return mWindowManager.getAppOrientation(r.appToken);
4396        }
4397    }
4398
4399    /**
4400     * This is the internal entry point for handling Activity.finish().
4401     *
4402     * @param token The Binder token referencing the Activity we want to finish.
4403     * @param resultCode Result code, if any, from this Activity.
4404     * @param resultData Result data (Intent), if any, from this Activity.
4405     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4406     *            the root Activity in the task.
4407     *
4408     * @return Returns true if the activity successfully finished, or false if it is still running.
4409     */
4410    @Override
4411    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4412            boolean finishTask) {
4413        // Refuse possible leaked file descriptors
4414        if (resultData != null && resultData.hasFileDescriptors() == true) {
4415            throw new IllegalArgumentException("File descriptors passed in Intent");
4416        }
4417
4418        synchronized(this) {
4419            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4420            if (r == null) {
4421                return true;
4422            }
4423            // Keep track of the root activity of the task before we finish it
4424            TaskRecord tr = r.task;
4425            ActivityRecord rootR = tr.getRootActivity();
4426            // Do not allow task to finish in Lock Task mode.
4427            if (tr == mStackSupervisor.mLockTaskModeTask) {
4428                if (rootR == r) {
4429                    mStackSupervisor.showLockTaskToast();
4430                    return false;
4431                }
4432            }
4433            if (mController != null) {
4434                // Find the first activity that is not finishing.
4435                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4436                if (next != null) {
4437                    // ask watcher if this is allowed
4438                    boolean resumeOK = true;
4439                    try {
4440                        resumeOK = mController.activityResuming(next.packageName);
4441                    } catch (RemoteException e) {
4442                        mController = null;
4443                        Watchdog.getInstance().setActivityController(null);
4444                    }
4445
4446                    if (!resumeOK) {
4447                        return false;
4448                    }
4449                }
4450            }
4451            final long origId = Binder.clearCallingIdentity();
4452            try {
4453                boolean res;
4454                if (finishTask && r == rootR) {
4455                    // If requested, remove the task that is associated to this activity only if it
4456                    // was the root activity in the task.  The result code and data is ignored because
4457                    // we don't support returning them across task boundaries.
4458                    res = removeTaskByIdLocked(tr.taskId, 0);
4459                } else {
4460                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4461                            resultData, "app-request", true);
4462                }
4463                return res;
4464            } finally {
4465                Binder.restoreCallingIdentity(origId);
4466            }
4467        }
4468    }
4469
4470    @Override
4471    public final void finishHeavyWeightApp() {
4472        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4473                != PackageManager.PERMISSION_GRANTED) {
4474            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4475                    + Binder.getCallingPid()
4476                    + ", uid=" + Binder.getCallingUid()
4477                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4478            Slog.w(TAG, msg);
4479            throw new SecurityException(msg);
4480        }
4481
4482        synchronized(this) {
4483            if (mHeavyWeightProcess == null) {
4484                return;
4485            }
4486
4487            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4488                    mHeavyWeightProcess.activities);
4489            for (int i=0; i<activities.size(); i++) {
4490                ActivityRecord r = activities.get(i);
4491                if (!r.finishing) {
4492                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4493                            null, "finish-heavy", true);
4494                }
4495            }
4496
4497            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4498                    mHeavyWeightProcess.userId, 0));
4499            mHeavyWeightProcess = null;
4500        }
4501    }
4502
4503    @Override
4504    public void crashApplication(int uid, int initialPid, String packageName,
4505            String message) {
4506        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4507                != PackageManager.PERMISSION_GRANTED) {
4508            String msg = "Permission Denial: crashApplication() from pid="
4509                    + Binder.getCallingPid()
4510                    + ", uid=" + Binder.getCallingUid()
4511                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4512            Slog.w(TAG, msg);
4513            throw new SecurityException(msg);
4514        }
4515
4516        synchronized(this) {
4517            ProcessRecord proc = null;
4518
4519            // Figure out which process to kill.  We don't trust that initialPid
4520            // still has any relation to current pids, so must scan through the
4521            // list.
4522            synchronized (mPidsSelfLocked) {
4523                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4524                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4525                    if (p.uid != uid) {
4526                        continue;
4527                    }
4528                    if (p.pid == initialPid) {
4529                        proc = p;
4530                        break;
4531                    }
4532                    if (p.pkgList.containsKey(packageName)) {
4533                        proc = p;
4534                    }
4535                }
4536            }
4537
4538            if (proc == null) {
4539                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4540                        + " initialPid=" + initialPid
4541                        + " packageName=" + packageName);
4542                return;
4543            }
4544
4545            if (proc.thread != null) {
4546                if (proc.pid == Process.myPid()) {
4547                    Log.w(TAG, "crashApplication: trying to crash self!");
4548                    return;
4549                }
4550                long ident = Binder.clearCallingIdentity();
4551                try {
4552                    proc.thread.scheduleCrash(message);
4553                } catch (RemoteException e) {
4554                }
4555                Binder.restoreCallingIdentity(ident);
4556            }
4557        }
4558    }
4559
4560    @Override
4561    public final void finishSubActivity(IBinder token, String resultWho,
4562            int requestCode) {
4563        synchronized(this) {
4564            final long origId = Binder.clearCallingIdentity();
4565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4566            if (r != null) {
4567                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4568            }
4569            Binder.restoreCallingIdentity(origId);
4570        }
4571    }
4572
4573    @Override
4574    public boolean finishActivityAffinity(IBinder token) {
4575        synchronized(this) {
4576            final long origId = Binder.clearCallingIdentity();
4577            try {
4578                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4579
4580                ActivityRecord rootR = r.task.getRootActivity();
4581                // Do not allow task to finish in Lock Task mode.
4582                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4583                    if (rootR == r) {
4584                        mStackSupervisor.showLockTaskToast();
4585                        return false;
4586                    }
4587                }
4588                boolean res = false;
4589                if (r != null) {
4590                    res = r.task.stack.finishActivityAffinityLocked(r);
4591                }
4592                return res;
4593            } finally {
4594                Binder.restoreCallingIdentity(origId);
4595            }
4596        }
4597    }
4598
4599    @Override
4600    public void finishVoiceTask(IVoiceInteractionSession session) {
4601        synchronized(this) {
4602            final long origId = Binder.clearCallingIdentity();
4603            try {
4604                mStackSupervisor.finishVoiceTask(session);
4605            } finally {
4606                Binder.restoreCallingIdentity(origId);
4607            }
4608        }
4609
4610    }
4611
4612    @Override
4613    public boolean releaseActivityInstance(IBinder token) {
4614        synchronized(this) {
4615            final long origId = Binder.clearCallingIdentity();
4616            try {
4617                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4618                if (r.task == null || r.task.stack == null) {
4619                    return false;
4620                }
4621                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4622            } finally {
4623                Binder.restoreCallingIdentity(origId);
4624            }
4625        }
4626    }
4627
4628    @Override
4629    public void releaseSomeActivities(IApplicationThread appInt) {
4630        synchronized(this) {
4631            final long origId = Binder.clearCallingIdentity();
4632            try {
4633                ProcessRecord app = getRecordForAppLocked(appInt);
4634                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4635            } finally {
4636                Binder.restoreCallingIdentity(origId);
4637            }
4638        }
4639    }
4640
4641    @Override
4642    public boolean willActivityBeVisible(IBinder token) {
4643        synchronized(this) {
4644            ActivityStack stack = ActivityRecord.getStackLocked(token);
4645            if (stack != null) {
4646                return stack.willActivityBeVisibleLocked(token);
4647            }
4648            return false;
4649        }
4650    }
4651
4652    @Override
4653    public void overridePendingTransition(IBinder token, String packageName,
4654            int enterAnim, int exitAnim) {
4655        synchronized(this) {
4656            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4657            if (self == null) {
4658                return;
4659            }
4660
4661            final long origId = Binder.clearCallingIdentity();
4662
4663            if (self.state == ActivityState.RESUMED
4664                    || self.state == ActivityState.PAUSING) {
4665                mWindowManager.overridePendingAppTransition(packageName,
4666                        enterAnim, exitAnim, null);
4667            }
4668
4669            Binder.restoreCallingIdentity(origId);
4670        }
4671    }
4672
4673    /**
4674     * Main function for removing an existing process from the activity manager
4675     * as a result of that process going away.  Clears out all connections
4676     * to the process.
4677     */
4678    private final void handleAppDiedLocked(ProcessRecord app,
4679            boolean restarting, boolean allowRestart) {
4680        int pid = app.pid;
4681        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4682        if (!restarting) {
4683            removeLruProcessLocked(app);
4684            if (pid > 0) {
4685                ProcessList.remove(pid);
4686            }
4687        }
4688
4689        if (mProfileProc == app) {
4690            clearProfilerLocked();
4691        }
4692
4693        // Remove this application's activities from active lists.
4694        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4695
4696        app.activities.clear();
4697
4698        if (app.instrumentationClass != null) {
4699            Slog.w(TAG, "Crash of app " + app.processName
4700                  + " running instrumentation " + app.instrumentationClass);
4701            Bundle info = new Bundle();
4702            info.putString("shortMsg", "Process crashed.");
4703            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4704        }
4705
4706        if (!restarting) {
4707            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4708                // If there was nothing to resume, and we are not already
4709                // restarting this process, but there is a visible activity that
4710                // is hosted by the process...  then make sure all visible
4711                // activities are running, taking care of restarting this
4712                // process.
4713                if (hasVisibleActivities) {
4714                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4715                }
4716            }
4717        }
4718    }
4719
4720    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4721        IBinder threadBinder = thread.asBinder();
4722        // Find the application record.
4723        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4724            ProcessRecord rec = mLruProcesses.get(i);
4725            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4726                return i;
4727            }
4728        }
4729        return -1;
4730    }
4731
4732    final ProcessRecord getRecordForAppLocked(
4733            IApplicationThread thread) {
4734        if (thread == null) {
4735            return null;
4736        }
4737
4738        int appIndex = getLRURecordIndexForAppLocked(thread);
4739        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4740    }
4741
4742    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4743        // If there are no longer any background processes running,
4744        // and the app that died was not running instrumentation,
4745        // then tell everyone we are now low on memory.
4746        boolean haveBg = false;
4747        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4748            ProcessRecord rec = mLruProcesses.get(i);
4749            if (rec.thread != null
4750                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4751                haveBg = true;
4752                break;
4753            }
4754        }
4755
4756        if (!haveBg) {
4757            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4758            if (doReport) {
4759                long now = SystemClock.uptimeMillis();
4760                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4761                    doReport = false;
4762                } else {
4763                    mLastMemUsageReportTime = now;
4764                }
4765            }
4766            final ArrayList<ProcessMemInfo> memInfos
4767                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4768            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4769            long now = SystemClock.uptimeMillis();
4770            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4771                ProcessRecord rec = mLruProcesses.get(i);
4772                if (rec == dyingProc || rec.thread == null) {
4773                    continue;
4774                }
4775                if (doReport) {
4776                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4777                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4778                }
4779                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4780                    // The low memory report is overriding any current
4781                    // state for a GC request.  Make sure to do
4782                    // heavy/important/visible/foreground processes first.
4783                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4784                        rec.lastRequestedGc = 0;
4785                    } else {
4786                        rec.lastRequestedGc = rec.lastLowMemory;
4787                    }
4788                    rec.reportLowMemory = true;
4789                    rec.lastLowMemory = now;
4790                    mProcessesToGc.remove(rec);
4791                    addProcessToGcListLocked(rec);
4792                }
4793            }
4794            if (doReport) {
4795                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4796                mHandler.sendMessage(msg);
4797            }
4798            scheduleAppGcsLocked();
4799        }
4800    }
4801
4802    final void appDiedLocked(ProcessRecord app) {
4803       appDiedLocked(app, app.pid, app.thread);
4804    }
4805
4806    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4807
4808        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4809        synchronized (stats) {
4810            stats.noteProcessDiedLocked(app.info.uid, pid);
4811        }
4812
4813        Process.killProcessQuiet(pid);
4814        Process.killProcessGroup(app.info.uid, pid);
4815        app.killed = true;
4816
4817        // Clean up already done if the process has been re-started.
4818        if (app.pid == pid && app.thread != null &&
4819                app.thread.asBinder() == thread.asBinder()) {
4820            boolean doLowMem = app.instrumentationClass == null;
4821            boolean doOomAdj = doLowMem;
4822            if (!app.killedByAm) {
4823                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4824                        + ") has died.");
4825                mAllowLowerMemLevel = true;
4826            } else {
4827                // Note that we always want to do oom adj to update our state with the
4828                // new number of procs.
4829                mAllowLowerMemLevel = false;
4830                doLowMem = false;
4831            }
4832            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4833            if (DEBUG_CLEANUP) Slog.v(
4834                TAG, "Dying app: " + app + ", pid: " + pid
4835                + ", thread: " + thread.asBinder());
4836            handleAppDiedLocked(app, false, true);
4837
4838            if (doOomAdj) {
4839                updateOomAdjLocked();
4840            }
4841            if (doLowMem) {
4842                doLowMemReportIfNeededLocked(app);
4843            }
4844        } else if (app.pid != pid) {
4845            // A new process has already been started.
4846            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4847                    + ") has died and restarted (pid " + app.pid + ").");
4848            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4849        } else if (DEBUG_PROCESSES) {
4850            Slog.d(TAG, "Received spurious death notification for thread "
4851                    + thread.asBinder());
4852        }
4853    }
4854
4855    /**
4856     * If a stack trace dump file is configured, dump process stack traces.
4857     * @param clearTraces causes the dump file to be erased prior to the new
4858     *    traces being written, if true; when false, the new traces will be
4859     *    appended to any existing file content.
4860     * @param firstPids of dalvik VM processes to dump stack traces for first
4861     * @param lastPids of dalvik VM processes to dump stack traces for last
4862     * @param nativeProcs optional list of native process names to dump stack crawls
4863     * @return file containing stack traces, or null if no dump file is configured
4864     */
4865    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4866            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4867        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4868        if (tracesPath == null || tracesPath.length() == 0) {
4869            return null;
4870        }
4871
4872        File tracesFile = new File(tracesPath);
4873        try {
4874            File tracesDir = tracesFile.getParentFile();
4875            if (!tracesDir.exists()) {
4876                tracesDir.mkdirs();
4877                if (!SELinux.restorecon(tracesDir)) {
4878                    return null;
4879                }
4880            }
4881            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4882
4883            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4884            tracesFile.createNewFile();
4885            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4886        } catch (IOException e) {
4887            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4888            return null;
4889        }
4890
4891        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4892        return tracesFile;
4893    }
4894
4895    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4896            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4897        // Use a FileObserver to detect when traces finish writing.
4898        // The order of traces is considered important to maintain for legibility.
4899        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4900            @Override
4901            public synchronized void onEvent(int event, String path) { notify(); }
4902        };
4903
4904        try {
4905            observer.startWatching();
4906
4907            // First collect all of the stacks of the most important pids.
4908            if (firstPids != null) {
4909                try {
4910                    int num = firstPids.size();
4911                    for (int i = 0; i < num; i++) {
4912                        synchronized (observer) {
4913                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4914                            observer.wait(200);  // Wait for write-close, give up after 200msec
4915                        }
4916                    }
4917                } catch (InterruptedException e) {
4918                    Log.wtf(TAG, e);
4919                }
4920            }
4921
4922            // Next collect the stacks of the native pids
4923            if (nativeProcs != null) {
4924                int[] pids = Process.getPidsForCommands(nativeProcs);
4925                if (pids != null) {
4926                    for (int pid : pids) {
4927                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4928                    }
4929                }
4930            }
4931
4932            // Lastly, measure CPU usage.
4933            if (processCpuTracker != null) {
4934                processCpuTracker.init();
4935                System.gc();
4936                processCpuTracker.update();
4937                try {
4938                    synchronized (processCpuTracker) {
4939                        processCpuTracker.wait(500); // measure over 1/2 second.
4940                    }
4941                } catch (InterruptedException e) {
4942                }
4943                processCpuTracker.update();
4944
4945                // We'll take the stack crawls of just the top apps using CPU.
4946                final int N = processCpuTracker.countWorkingStats();
4947                int numProcs = 0;
4948                for (int i=0; i<N && numProcs<5; i++) {
4949                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4950                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4951                        numProcs++;
4952                        try {
4953                            synchronized (observer) {
4954                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4955                                observer.wait(200);  // Wait for write-close, give up after 200msec
4956                            }
4957                        } catch (InterruptedException e) {
4958                            Log.wtf(TAG, e);
4959                        }
4960
4961                    }
4962                }
4963            }
4964        } finally {
4965            observer.stopWatching();
4966        }
4967    }
4968
4969    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4970        if (true || IS_USER_BUILD) {
4971            return;
4972        }
4973        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4974        if (tracesPath == null || tracesPath.length() == 0) {
4975            return;
4976        }
4977
4978        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4979        StrictMode.allowThreadDiskWrites();
4980        try {
4981            final File tracesFile = new File(tracesPath);
4982            final File tracesDir = tracesFile.getParentFile();
4983            final File tracesTmp = new File(tracesDir, "__tmp__");
4984            try {
4985                if (!tracesDir.exists()) {
4986                    tracesDir.mkdirs();
4987                    if (!SELinux.restorecon(tracesDir.getPath())) {
4988                        return;
4989                    }
4990                }
4991                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4992
4993                if (tracesFile.exists()) {
4994                    tracesTmp.delete();
4995                    tracesFile.renameTo(tracesTmp);
4996                }
4997                StringBuilder sb = new StringBuilder();
4998                Time tobj = new Time();
4999                tobj.set(System.currentTimeMillis());
5000                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5001                sb.append(": ");
5002                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5003                sb.append(" since ");
5004                sb.append(msg);
5005                FileOutputStream fos = new FileOutputStream(tracesFile);
5006                fos.write(sb.toString().getBytes());
5007                if (app == null) {
5008                    fos.write("\n*** No application process!".getBytes());
5009                }
5010                fos.close();
5011                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5012            } catch (IOException e) {
5013                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5014                return;
5015            }
5016
5017            if (app != null) {
5018                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5019                firstPids.add(app.pid);
5020                dumpStackTraces(tracesPath, firstPids, null, null, null);
5021            }
5022
5023            File lastTracesFile = null;
5024            File curTracesFile = null;
5025            for (int i=9; i>=0; i--) {
5026                String name = String.format(Locale.US, "slow%02d.txt", i);
5027                curTracesFile = new File(tracesDir, name);
5028                if (curTracesFile.exists()) {
5029                    if (lastTracesFile != null) {
5030                        curTracesFile.renameTo(lastTracesFile);
5031                    } else {
5032                        curTracesFile.delete();
5033                    }
5034                }
5035                lastTracesFile = curTracesFile;
5036            }
5037            tracesFile.renameTo(curTracesFile);
5038            if (tracesTmp.exists()) {
5039                tracesTmp.renameTo(tracesFile);
5040            }
5041        } finally {
5042            StrictMode.setThreadPolicy(oldPolicy);
5043        }
5044    }
5045
5046    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5047            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5048        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5049        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5050
5051        if (mController != null) {
5052            try {
5053                // 0 == continue, -1 = kill process immediately
5054                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5055                if (res < 0 && app.pid != MY_PID) {
5056                    app.kill("anr", true);
5057                }
5058            } catch (RemoteException e) {
5059                mController = null;
5060                Watchdog.getInstance().setActivityController(null);
5061            }
5062        }
5063
5064        long anrTime = SystemClock.uptimeMillis();
5065        if (MONITOR_CPU_USAGE) {
5066            updateCpuStatsNow();
5067        }
5068
5069        synchronized (this) {
5070            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5071            if (mShuttingDown) {
5072                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5073                return;
5074            } else if (app.notResponding) {
5075                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5076                return;
5077            } else if (app.crashing) {
5078                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5079                return;
5080            }
5081
5082            // In case we come through here for the same app before completing
5083            // this one, mark as anring now so we will bail out.
5084            app.notResponding = true;
5085
5086            // Log the ANR to the event log.
5087            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5088                    app.processName, app.info.flags, annotation);
5089
5090            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5091            firstPids.add(app.pid);
5092
5093            int parentPid = app.pid;
5094            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5095            if (parentPid != app.pid) firstPids.add(parentPid);
5096
5097            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5098
5099            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5100                ProcessRecord r = mLruProcesses.get(i);
5101                if (r != null && r.thread != null) {
5102                    int pid = r.pid;
5103                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5104                        if (r.persistent) {
5105                            firstPids.add(pid);
5106                        } else {
5107                            lastPids.put(pid, Boolean.TRUE);
5108                        }
5109                    }
5110                }
5111            }
5112        }
5113
5114        // Log the ANR to the main log.
5115        StringBuilder info = new StringBuilder();
5116        info.setLength(0);
5117        info.append("ANR in ").append(app.processName);
5118        if (activity != null && activity.shortComponentName != null) {
5119            info.append(" (").append(activity.shortComponentName).append(")");
5120        }
5121        info.append("\n");
5122        info.append("PID: ").append(app.pid).append("\n");
5123        if (annotation != null) {
5124            info.append("Reason: ").append(annotation).append("\n");
5125        }
5126        if (parent != null && parent != activity) {
5127            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5128        }
5129
5130        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5131
5132        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5133                NATIVE_STACKS_OF_INTEREST);
5134
5135        String cpuInfo = null;
5136        if (MONITOR_CPU_USAGE) {
5137            updateCpuStatsNow();
5138            synchronized (mProcessCpuTracker) {
5139                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5140            }
5141            info.append(processCpuTracker.printCurrentLoad());
5142            info.append(cpuInfo);
5143        }
5144
5145        info.append(processCpuTracker.printCurrentState(anrTime));
5146
5147        Slog.e(TAG, info.toString());
5148        if (tracesFile == null) {
5149            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5150            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5151        }
5152
5153        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5154                cpuInfo, tracesFile, null);
5155
5156        if (mController != null) {
5157            try {
5158                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5159                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5160                if (res != 0) {
5161                    if (res < 0 && app.pid != MY_PID) {
5162                        app.kill("anr", true);
5163                    } else {
5164                        synchronized (this) {
5165                            mServices.scheduleServiceTimeoutLocked(app);
5166                        }
5167                    }
5168                    return;
5169                }
5170            } catch (RemoteException e) {
5171                mController = null;
5172                Watchdog.getInstance().setActivityController(null);
5173            }
5174        }
5175
5176        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5177        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5178                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5179
5180        synchronized (this) {
5181            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5182                app.kill("bg anr", true);
5183                return;
5184            }
5185
5186            // Set the app's notResponding state, and look up the errorReportReceiver
5187            makeAppNotRespondingLocked(app,
5188                    activity != null ? activity.shortComponentName : null,
5189                    annotation != null ? "ANR " + annotation : "ANR",
5190                    info.toString());
5191
5192            // Bring up the infamous App Not Responding dialog
5193            Message msg = Message.obtain();
5194            HashMap<String, Object> map = new HashMap<String, Object>();
5195            msg.what = SHOW_NOT_RESPONDING_MSG;
5196            msg.obj = map;
5197            msg.arg1 = aboveSystem ? 1 : 0;
5198            map.put("app", app);
5199            if (activity != null) {
5200                map.put("activity", activity);
5201            }
5202
5203            mHandler.sendMessage(msg);
5204        }
5205    }
5206
5207    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5208        if (!mLaunchWarningShown) {
5209            mLaunchWarningShown = true;
5210            mHandler.post(new Runnable() {
5211                @Override
5212                public void run() {
5213                    synchronized (ActivityManagerService.this) {
5214                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5215                        d.show();
5216                        mHandler.postDelayed(new Runnable() {
5217                            @Override
5218                            public void run() {
5219                                synchronized (ActivityManagerService.this) {
5220                                    d.dismiss();
5221                                    mLaunchWarningShown = false;
5222                                }
5223                            }
5224                        }, 4000);
5225                    }
5226                }
5227            });
5228        }
5229    }
5230
5231    @Override
5232    public boolean clearApplicationUserData(final String packageName,
5233            final IPackageDataObserver observer, int userId) {
5234        enforceNotIsolatedCaller("clearApplicationUserData");
5235        int uid = Binder.getCallingUid();
5236        int pid = Binder.getCallingPid();
5237        userId = handleIncomingUser(pid, uid,
5238                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5239        long callingId = Binder.clearCallingIdentity();
5240        try {
5241            IPackageManager pm = AppGlobals.getPackageManager();
5242            int pkgUid = -1;
5243            synchronized(this) {
5244                try {
5245                    pkgUid = pm.getPackageUid(packageName, userId);
5246                } catch (RemoteException e) {
5247                }
5248                if (pkgUid == -1) {
5249                    Slog.w(TAG, "Invalid packageName: " + packageName);
5250                    if (observer != null) {
5251                        try {
5252                            observer.onRemoveCompleted(packageName, false);
5253                        } catch (RemoteException e) {
5254                            Slog.i(TAG, "Observer no longer exists.");
5255                        }
5256                    }
5257                    return false;
5258                }
5259                if (uid == pkgUid || checkComponentPermission(
5260                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5261                        pid, uid, -1, true)
5262                        == PackageManager.PERMISSION_GRANTED) {
5263                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5264                } else {
5265                    throw new SecurityException("PID " + pid + " does not have permission "
5266                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5267                                    + " of package " + packageName);
5268                }
5269
5270                // Remove all tasks match the cleared application package and user
5271                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5272                    final TaskRecord tr = mRecentTasks.get(i);
5273                    final String taskPackageName =
5274                            tr.getBaseIntent().getComponent().getPackageName();
5275                    if (tr.userId != userId) continue;
5276                    if (!taskPackageName.equals(packageName)) continue;
5277                    removeTaskByIdLocked(tr.taskId, 0);
5278                }
5279            }
5280
5281            try {
5282                // Clear application user data
5283                pm.clearApplicationUserData(packageName, observer, userId);
5284
5285                synchronized(this) {
5286                    // Remove all permissions granted from/to this package
5287                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5288                }
5289
5290                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5291                        Uri.fromParts("package", packageName, null));
5292                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5293                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5294                        null, null, 0, null, null, null, false, false, userId);
5295            } catch (RemoteException e) {
5296            }
5297        } finally {
5298            Binder.restoreCallingIdentity(callingId);
5299        }
5300        return true;
5301    }
5302
5303    @Override
5304    public void killBackgroundProcesses(final String packageName, int userId) {
5305        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5306                != PackageManager.PERMISSION_GRANTED &&
5307                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5308                        != PackageManager.PERMISSION_GRANTED) {
5309            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5310                    + Binder.getCallingPid()
5311                    + ", uid=" + Binder.getCallingUid()
5312                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5313            Slog.w(TAG, msg);
5314            throw new SecurityException(msg);
5315        }
5316
5317        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5318                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5319        long callingId = Binder.clearCallingIdentity();
5320        try {
5321            IPackageManager pm = AppGlobals.getPackageManager();
5322            synchronized(this) {
5323                int appId = -1;
5324                try {
5325                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5326                } catch (RemoteException e) {
5327                }
5328                if (appId == -1) {
5329                    Slog.w(TAG, "Invalid packageName: " + packageName);
5330                    return;
5331                }
5332                killPackageProcessesLocked(packageName, appId, userId,
5333                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5334            }
5335        } finally {
5336            Binder.restoreCallingIdentity(callingId);
5337        }
5338    }
5339
5340    @Override
5341    public void killAllBackgroundProcesses() {
5342        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5343                != PackageManager.PERMISSION_GRANTED) {
5344            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5345                    + Binder.getCallingPid()
5346                    + ", uid=" + Binder.getCallingUid()
5347                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5348            Slog.w(TAG, msg);
5349            throw new SecurityException(msg);
5350        }
5351
5352        long callingId = Binder.clearCallingIdentity();
5353        try {
5354            synchronized(this) {
5355                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5356                final int NP = mProcessNames.getMap().size();
5357                for (int ip=0; ip<NP; ip++) {
5358                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5359                    final int NA = apps.size();
5360                    for (int ia=0; ia<NA; ia++) {
5361                        ProcessRecord app = apps.valueAt(ia);
5362                        if (app.persistent) {
5363                            // we don't kill persistent processes
5364                            continue;
5365                        }
5366                        if (app.removed) {
5367                            procs.add(app);
5368                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5369                            app.removed = true;
5370                            procs.add(app);
5371                        }
5372                    }
5373                }
5374
5375                int N = procs.size();
5376                for (int i=0; i<N; i++) {
5377                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5378                }
5379                mAllowLowerMemLevel = true;
5380                updateOomAdjLocked();
5381                doLowMemReportIfNeededLocked(null);
5382            }
5383        } finally {
5384            Binder.restoreCallingIdentity(callingId);
5385        }
5386    }
5387
5388    @Override
5389    public void forceStopPackage(final String packageName, int userId) {
5390        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5391                != PackageManager.PERMISSION_GRANTED) {
5392            String msg = "Permission Denial: forceStopPackage() from pid="
5393                    + Binder.getCallingPid()
5394                    + ", uid=" + Binder.getCallingUid()
5395                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5396            Slog.w(TAG, msg);
5397            throw new SecurityException(msg);
5398        }
5399        final int callingPid = Binder.getCallingPid();
5400        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5401                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5402        long callingId = Binder.clearCallingIdentity();
5403        try {
5404            IPackageManager pm = AppGlobals.getPackageManager();
5405            synchronized(this) {
5406                int[] users = userId == UserHandle.USER_ALL
5407                        ? getUsersLocked() : new int[] { userId };
5408                for (int user : users) {
5409                    int pkgUid = -1;
5410                    try {
5411                        pkgUid = pm.getPackageUid(packageName, user);
5412                    } catch (RemoteException e) {
5413                    }
5414                    if (pkgUid == -1) {
5415                        Slog.w(TAG, "Invalid packageName: " + packageName);
5416                        continue;
5417                    }
5418                    try {
5419                        pm.setPackageStoppedState(packageName, true, user);
5420                    } catch (RemoteException e) {
5421                    } catch (IllegalArgumentException e) {
5422                        Slog.w(TAG, "Failed trying to unstop package "
5423                                + packageName + ": " + e);
5424                    }
5425                    if (isUserRunningLocked(user, false)) {
5426                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5427                    }
5428                }
5429            }
5430        } finally {
5431            Binder.restoreCallingIdentity(callingId);
5432        }
5433    }
5434
5435    @Override
5436    public void addPackageDependency(String packageName) {
5437        synchronized (this) {
5438            int callingPid = Binder.getCallingPid();
5439            if (callingPid == Process.myPid()) {
5440                //  Yeah, um, no.
5441                Slog.w(TAG, "Can't addPackageDependency on system process");
5442                return;
5443            }
5444            ProcessRecord proc;
5445            synchronized (mPidsSelfLocked) {
5446                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5447            }
5448            if (proc != null) {
5449                if (proc.pkgDeps == null) {
5450                    proc.pkgDeps = new ArraySet<String>(1);
5451                }
5452                proc.pkgDeps.add(packageName);
5453            }
5454        }
5455    }
5456
5457    /*
5458     * The pkg name and app id have to be specified.
5459     */
5460    @Override
5461    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5462        if (pkg == null) {
5463            return;
5464        }
5465        // Make sure the uid is valid.
5466        if (appid < 0) {
5467            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5468            return;
5469        }
5470        int callerUid = Binder.getCallingUid();
5471        // Only the system server can kill an application
5472        if (callerUid == Process.SYSTEM_UID) {
5473            // Post an aysnc message to kill the application
5474            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5475            msg.arg1 = appid;
5476            msg.arg2 = 0;
5477            Bundle bundle = new Bundle();
5478            bundle.putString("pkg", pkg);
5479            bundle.putString("reason", reason);
5480            msg.obj = bundle;
5481            mHandler.sendMessage(msg);
5482        } else {
5483            throw new SecurityException(callerUid + " cannot kill pkg: " +
5484                    pkg);
5485        }
5486    }
5487
5488    @Override
5489    public void closeSystemDialogs(String reason) {
5490        enforceNotIsolatedCaller("closeSystemDialogs");
5491
5492        final int pid = Binder.getCallingPid();
5493        final int uid = Binder.getCallingUid();
5494        final long origId = Binder.clearCallingIdentity();
5495        try {
5496            synchronized (this) {
5497                // Only allow this from foreground processes, so that background
5498                // applications can't abuse it to prevent system UI from being shown.
5499                if (uid >= Process.FIRST_APPLICATION_UID) {
5500                    ProcessRecord proc;
5501                    synchronized (mPidsSelfLocked) {
5502                        proc = mPidsSelfLocked.get(pid);
5503                    }
5504                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5505                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5506                                + " from background process " + proc);
5507                        return;
5508                    }
5509                }
5510                closeSystemDialogsLocked(reason);
5511            }
5512        } finally {
5513            Binder.restoreCallingIdentity(origId);
5514        }
5515    }
5516
5517    void closeSystemDialogsLocked(String reason) {
5518        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5519        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5520                | Intent.FLAG_RECEIVER_FOREGROUND);
5521        if (reason != null) {
5522            intent.putExtra("reason", reason);
5523        }
5524        mWindowManager.closeSystemDialogs(reason);
5525
5526        mStackSupervisor.closeSystemDialogsLocked();
5527
5528        broadcastIntentLocked(null, null, intent, null,
5529                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5530                Process.SYSTEM_UID, UserHandle.USER_ALL);
5531    }
5532
5533    @Override
5534    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5535        enforceNotIsolatedCaller("getProcessMemoryInfo");
5536        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5537        for (int i=pids.length-1; i>=0; i--) {
5538            ProcessRecord proc;
5539            int oomAdj;
5540            synchronized (this) {
5541                synchronized (mPidsSelfLocked) {
5542                    proc = mPidsSelfLocked.get(pids[i]);
5543                    oomAdj = proc != null ? proc.setAdj : 0;
5544                }
5545            }
5546            infos[i] = new Debug.MemoryInfo();
5547            Debug.getMemoryInfo(pids[i], infos[i]);
5548            if (proc != null) {
5549                synchronized (this) {
5550                    if (proc.thread != null && proc.setAdj == oomAdj) {
5551                        // Record this for posterity if the process has been stable.
5552                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5553                                infos[i].getTotalUss(), false, proc.pkgList);
5554                    }
5555                }
5556            }
5557        }
5558        return infos;
5559    }
5560
5561    @Override
5562    public long[] getProcessPss(int[] pids) {
5563        enforceNotIsolatedCaller("getProcessPss");
5564        long[] pss = new long[pids.length];
5565        for (int i=pids.length-1; i>=0; i--) {
5566            ProcessRecord proc;
5567            int oomAdj;
5568            synchronized (this) {
5569                synchronized (mPidsSelfLocked) {
5570                    proc = mPidsSelfLocked.get(pids[i]);
5571                    oomAdj = proc != null ? proc.setAdj : 0;
5572                }
5573            }
5574            long[] tmpUss = new long[1];
5575            pss[i] = Debug.getPss(pids[i], tmpUss);
5576            if (proc != null) {
5577                synchronized (this) {
5578                    if (proc.thread != null && proc.setAdj == oomAdj) {
5579                        // Record this for posterity if the process has been stable.
5580                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5581                    }
5582                }
5583            }
5584        }
5585        return pss;
5586    }
5587
5588    @Override
5589    public void killApplicationProcess(String processName, int uid) {
5590        if (processName == null) {
5591            return;
5592        }
5593
5594        int callerUid = Binder.getCallingUid();
5595        // Only the system server can kill an application
5596        if (callerUid == Process.SYSTEM_UID) {
5597            synchronized (this) {
5598                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5599                if (app != null && app.thread != null) {
5600                    try {
5601                        app.thread.scheduleSuicide();
5602                    } catch (RemoteException e) {
5603                        // If the other end already died, then our work here is done.
5604                    }
5605                } else {
5606                    Slog.w(TAG, "Process/uid not found attempting kill of "
5607                            + processName + " / " + uid);
5608                }
5609            }
5610        } else {
5611            throw new SecurityException(callerUid + " cannot kill app process: " +
5612                    processName);
5613        }
5614    }
5615
5616    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5617        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5618                false, true, false, false, UserHandle.getUserId(uid), reason);
5619        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5620                Uri.fromParts("package", packageName, null));
5621        if (!mProcessesReady) {
5622            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5623                    | Intent.FLAG_RECEIVER_FOREGROUND);
5624        }
5625        intent.putExtra(Intent.EXTRA_UID, uid);
5626        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5627        broadcastIntentLocked(null, null, intent,
5628                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5629                false, false,
5630                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5631    }
5632
5633    private void forceStopUserLocked(int userId, String reason) {
5634        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5635        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5636        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5637                | Intent.FLAG_RECEIVER_FOREGROUND);
5638        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5639        broadcastIntentLocked(null, null, intent,
5640                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5641                false, false,
5642                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5643    }
5644
5645    private final boolean killPackageProcessesLocked(String packageName, int appId,
5646            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5647            boolean doit, boolean evenPersistent, String reason) {
5648        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5649
5650        // Remove all processes this package may have touched: all with the
5651        // same UID (except for the system or root user), and all whose name
5652        // matches the package name.
5653        final int NP = mProcessNames.getMap().size();
5654        for (int ip=0; ip<NP; ip++) {
5655            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5656            final int NA = apps.size();
5657            for (int ia=0; ia<NA; ia++) {
5658                ProcessRecord app = apps.valueAt(ia);
5659                if (app.persistent && !evenPersistent) {
5660                    // we don't kill persistent processes
5661                    continue;
5662                }
5663                if (app.removed) {
5664                    if (doit) {
5665                        procs.add(app);
5666                    }
5667                    continue;
5668                }
5669
5670                // Skip process if it doesn't meet our oom adj requirement.
5671                if (app.setAdj < minOomAdj) {
5672                    continue;
5673                }
5674
5675                // If no package is specified, we call all processes under the
5676                // give user id.
5677                if (packageName == null) {
5678                    if (app.userId != userId) {
5679                        continue;
5680                    }
5681                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5682                        continue;
5683                    }
5684                // Package has been specified, we want to hit all processes
5685                // that match it.  We need to qualify this by the processes
5686                // that are running under the specified app and user ID.
5687                } else {
5688                    final boolean isDep = app.pkgDeps != null
5689                            && app.pkgDeps.contains(packageName);
5690                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5691                        continue;
5692                    }
5693                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5694                        continue;
5695                    }
5696                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5697                        continue;
5698                    }
5699                }
5700
5701                // Process has passed all conditions, kill it!
5702                if (!doit) {
5703                    return true;
5704                }
5705                app.removed = true;
5706                procs.add(app);
5707            }
5708        }
5709
5710        int N = procs.size();
5711        for (int i=0; i<N; i++) {
5712            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5713        }
5714        updateOomAdjLocked();
5715        return N > 0;
5716    }
5717
5718    private final boolean forceStopPackageLocked(String name, int appId,
5719            boolean callerWillRestart, boolean purgeCache, boolean doit,
5720            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5721        int i;
5722        int N;
5723
5724        if (userId == UserHandle.USER_ALL && name == null) {
5725            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5726        }
5727
5728        if (appId < 0 && name != null) {
5729            try {
5730                appId = UserHandle.getAppId(
5731                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5732            } catch (RemoteException e) {
5733            }
5734        }
5735
5736        if (doit) {
5737            if (name != null) {
5738                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5739                        + " user=" + userId + ": " + reason);
5740            } else {
5741                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5742            }
5743
5744            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5745            for (int ip=pmap.size()-1; ip>=0; ip--) {
5746                SparseArray<Long> ba = pmap.valueAt(ip);
5747                for (i=ba.size()-1; i>=0; i--) {
5748                    boolean remove = false;
5749                    final int entUid = ba.keyAt(i);
5750                    if (name != null) {
5751                        if (userId == UserHandle.USER_ALL) {
5752                            if (UserHandle.getAppId(entUid) == appId) {
5753                                remove = true;
5754                            }
5755                        } else {
5756                            if (entUid == UserHandle.getUid(userId, appId)) {
5757                                remove = true;
5758                            }
5759                        }
5760                    } else if (UserHandle.getUserId(entUid) == userId) {
5761                        remove = true;
5762                    }
5763                    if (remove) {
5764                        ba.removeAt(i);
5765                    }
5766                }
5767                if (ba.size() == 0) {
5768                    pmap.removeAt(ip);
5769                }
5770            }
5771        }
5772
5773        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5774                -100, callerWillRestart, true, doit, evenPersistent,
5775                name == null ? ("stop user " + userId) : ("stop " + name));
5776
5777        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5778            if (!doit) {
5779                return true;
5780            }
5781            didSomething = true;
5782        }
5783
5784        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5785            if (!doit) {
5786                return true;
5787            }
5788            didSomething = true;
5789        }
5790
5791        if (name == null) {
5792            // Remove all sticky broadcasts from this user.
5793            mStickyBroadcasts.remove(userId);
5794        }
5795
5796        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5797        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5798                userId, providers)) {
5799            if (!doit) {
5800                return true;
5801            }
5802            didSomething = true;
5803        }
5804        N = providers.size();
5805        for (i=0; i<N; i++) {
5806            removeDyingProviderLocked(null, providers.get(i), true);
5807        }
5808
5809        // Remove transient permissions granted from/to this package/user
5810        removeUriPermissionsForPackageLocked(name, userId, false);
5811
5812        if (name == null || uninstalling) {
5813            // Remove pending intents.  For now we only do this when force
5814            // stopping users, because we have some problems when doing this
5815            // for packages -- app widgets are not currently cleaned up for
5816            // such packages, so they can be left with bad pending intents.
5817            if (mIntentSenderRecords.size() > 0) {
5818                Iterator<WeakReference<PendingIntentRecord>> it
5819                        = mIntentSenderRecords.values().iterator();
5820                while (it.hasNext()) {
5821                    WeakReference<PendingIntentRecord> wpir = it.next();
5822                    if (wpir == null) {
5823                        it.remove();
5824                        continue;
5825                    }
5826                    PendingIntentRecord pir = wpir.get();
5827                    if (pir == null) {
5828                        it.remove();
5829                        continue;
5830                    }
5831                    if (name == null) {
5832                        // Stopping user, remove all objects for the user.
5833                        if (pir.key.userId != userId) {
5834                            // Not the same user, skip it.
5835                            continue;
5836                        }
5837                    } else {
5838                        if (UserHandle.getAppId(pir.uid) != appId) {
5839                            // Different app id, skip it.
5840                            continue;
5841                        }
5842                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5843                            // Different user, skip it.
5844                            continue;
5845                        }
5846                        if (!pir.key.packageName.equals(name)) {
5847                            // Different package, skip it.
5848                            continue;
5849                        }
5850                    }
5851                    if (!doit) {
5852                        return true;
5853                    }
5854                    didSomething = true;
5855                    it.remove();
5856                    pir.canceled = true;
5857                    if (pir.key.activity != null) {
5858                        pir.key.activity.pendingResults.remove(pir.ref);
5859                    }
5860                }
5861            }
5862        }
5863
5864        if (doit) {
5865            if (purgeCache && name != null) {
5866                AttributeCache ac = AttributeCache.instance();
5867                if (ac != null) {
5868                    ac.removePackage(name);
5869                }
5870            }
5871            if (mBooted) {
5872                mStackSupervisor.resumeTopActivitiesLocked();
5873                mStackSupervisor.scheduleIdleLocked();
5874            }
5875        }
5876
5877        return didSomething;
5878    }
5879
5880    private final boolean removeProcessLocked(ProcessRecord app,
5881            boolean callerWillRestart, boolean allowRestart, String reason) {
5882        final String name = app.processName;
5883        final int uid = app.uid;
5884        if (DEBUG_PROCESSES) Slog.d(
5885            TAG, "Force removing proc " + app.toShortString() + " (" + name
5886            + "/" + uid + ")");
5887
5888        mProcessNames.remove(name, uid);
5889        mIsolatedProcesses.remove(app.uid);
5890        if (mHeavyWeightProcess == app) {
5891            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5892                    mHeavyWeightProcess.userId, 0));
5893            mHeavyWeightProcess = null;
5894        }
5895        boolean needRestart = false;
5896        if (app.pid > 0 && app.pid != MY_PID) {
5897            int pid = app.pid;
5898            synchronized (mPidsSelfLocked) {
5899                mPidsSelfLocked.remove(pid);
5900                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5901            }
5902            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5903            if (app.isolated) {
5904                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5905            }
5906            app.kill(reason, true);
5907            handleAppDiedLocked(app, true, allowRestart);
5908            removeLruProcessLocked(app);
5909
5910            if (app.persistent && !app.isolated) {
5911                if (!callerWillRestart) {
5912                    addAppLocked(app.info, false, null /* ABI override */);
5913                } else {
5914                    needRestart = true;
5915                }
5916            }
5917        } else {
5918            mRemovedProcesses.add(app);
5919        }
5920
5921        return needRestart;
5922    }
5923
5924    private final void processStartTimedOutLocked(ProcessRecord app) {
5925        final int pid = app.pid;
5926        boolean gone = false;
5927        synchronized (mPidsSelfLocked) {
5928            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5929            if (knownApp != null && knownApp.thread == null) {
5930                mPidsSelfLocked.remove(pid);
5931                gone = true;
5932            }
5933        }
5934
5935        if (gone) {
5936            Slog.w(TAG, "Process " + app + " failed to attach");
5937            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5938                    pid, app.uid, app.processName);
5939            mProcessNames.remove(app.processName, app.uid);
5940            mIsolatedProcesses.remove(app.uid);
5941            if (mHeavyWeightProcess == app) {
5942                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5943                        mHeavyWeightProcess.userId, 0));
5944                mHeavyWeightProcess = null;
5945            }
5946            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5947            if (app.isolated) {
5948                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5949            }
5950            // Take care of any launching providers waiting for this process.
5951            checkAppInLaunchingProvidersLocked(app, true);
5952            // Take care of any services that are waiting for the process.
5953            mServices.processStartTimedOutLocked(app);
5954            app.kill("start timeout", true);
5955            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5956                Slog.w(TAG, "Unattached app died before backup, skipping");
5957                try {
5958                    IBackupManager bm = IBackupManager.Stub.asInterface(
5959                            ServiceManager.getService(Context.BACKUP_SERVICE));
5960                    bm.agentDisconnected(app.info.packageName);
5961                } catch (RemoteException e) {
5962                    // Can't happen; the backup manager is local
5963                }
5964            }
5965            if (isPendingBroadcastProcessLocked(pid)) {
5966                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5967                skipPendingBroadcastLocked(pid);
5968            }
5969        } else {
5970            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5971        }
5972    }
5973
5974    private final boolean attachApplicationLocked(IApplicationThread thread,
5975            int pid) {
5976
5977        // Find the application record that is being attached...  either via
5978        // the pid if we are running in multiple processes, or just pull the
5979        // next app record if we are emulating process with anonymous threads.
5980        ProcessRecord app;
5981        if (pid != MY_PID && pid >= 0) {
5982            synchronized (mPidsSelfLocked) {
5983                app = mPidsSelfLocked.get(pid);
5984            }
5985        } else {
5986            app = null;
5987        }
5988
5989        if (app == null) {
5990            Slog.w(TAG, "No pending application record for pid " + pid
5991                    + " (IApplicationThread " + thread + "); dropping process");
5992            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5993            if (pid > 0 && pid != MY_PID) {
5994                Process.killProcessQuiet(pid);
5995                //TODO: Process.killProcessGroup(app.info.uid, pid);
5996            } else {
5997                try {
5998                    thread.scheduleExit();
5999                } catch (Exception e) {
6000                    // Ignore exceptions.
6001                }
6002            }
6003            return false;
6004        }
6005
6006        // If this application record is still attached to a previous
6007        // process, clean it up now.
6008        if (app.thread != null) {
6009            handleAppDiedLocked(app, true, true);
6010        }
6011
6012        // Tell the process all about itself.
6013
6014        if (localLOGV) Slog.v(
6015                TAG, "Binding process pid " + pid + " to record " + app);
6016
6017        final String processName = app.processName;
6018        try {
6019            AppDeathRecipient adr = new AppDeathRecipient(
6020                    app, pid, thread);
6021            thread.asBinder().linkToDeath(adr, 0);
6022            app.deathRecipient = adr;
6023        } catch (RemoteException e) {
6024            app.resetPackageList(mProcessStats);
6025            startProcessLocked(app, "link fail", processName);
6026            return false;
6027        }
6028
6029        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6030
6031        app.makeActive(thread, mProcessStats);
6032        app.curAdj = app.setAdj = -100;
6033        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6034        app.forcingToForeground = null;
6035        updateProcessForegroundLocked(app, false, false);
6036        app.hasShownUi = false;
6037        app.debugging = false;
6038        app.cached = false;
6039
6040        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6041
6042        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6043        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6044
6045        if (!normalMode) {
6046            Slog.i(TAG, "Launching preboot mode app: " + app);
6047        }
6048
6049        if (localLOGV) Slog.v(
6050            TAG, "New app record " + app
6051            + " thread=" + thread.asBinder() + " pid=" + pid);
6052        try {
6053            int testMode = IApplicationThread.DEBUG_OFF;
6054            if (mDebugApp != null && mDebugApp.equals(processName)) {
6055                testMode = mWaitForDebugger
6056                    ? IApplicationThread.DEBUG_WAIT
6057                    : IApplicationThread.DEBUG_ON;
6058                app.debugging = true;
6059                if (mDebugTransient) {
6060                    mDebugApp = mOrigDebugApp;
6061                    mWaitForDebugger = mOrigWaitForDebugger;
6062                }
6063            }
6064            String profileFile = app.instrumentationProfileFile;
6065            ParcelFileDescriptor profileFd = null;
6066            int samplingInterval = 0;
6067            boolean profileAutoStop = false;
6068            if (mProfileApp != null && mProfileApp.equals(processName)) {
6069                mProfileProc = app;
6070                profileFile = mProfileFile;
6071                profileFd = mProfileFd;
6072                samplingInterval = mSamplingInterval;
6073                profileAutoStop = mAutoStopProfiler;
6074            }
6075            boolean enableOpenGlTrace = false;
6076            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6077                enableOpenGlTrace = true;
6078                mOpenGlTraceApp = null;
6079            }
6080
6081            // If the app is being launched for restore or full backup, set it up specially
6082            boolean isRestrictedBackupMode = false;
6083            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6084                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6085                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6086                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6087            }
6088
6089            ensurePackageDexOpt(app.instrumentationInfo != null
6090                    ? app.instrumentationInfo.packageName
6091                    : app.info.packageName);
6092            if (app.instrumentationClass != null) {
6093                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6094            }
6095            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6096                    + processName + " with config " + mConfiguration);
6097            ApplicationInfo appInfo = app.instrumentationInfo != null
6098                    ? app.instrumentationInfo : app.info;
6099            app.compat = compatibilityInfoForPackageLocked(appInfo);
6100            if (profileFd != null) {
6101                profileFd = profileFd.dup();
6102            }
6103            ProfilerInfo profilerInfo = profileFile == null ? null
6104                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6105            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6106                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6107                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6108                    isRestrictedBackupMode || !normalMode, app.persistent,
6109                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6110                    mCoreSettingsObserver.getCoreSettingsLocked());
6111            updateLruProcessLocked(app, false, null);
6112            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6113        } catch (Exception e) {
6114            // todo: Yikes!  What should we do?  For now we will try to
6115            // start another process, but that could easily get us in
6116            // an infinite loop of restarting processes...
6117            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6118
6119            app.resetPackageList(mProcessStats);
6120            app.unlinkDeathRecipient();
6121            startProcessLocked(app, "bind fail", processName);
6122            return false;
6123        }
6124
6125        // Remove this record from the list of starting applications.
6126        mPersistentStartingProcesses.remove(app);
6127        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6128                "Attach application locked removing on hold: " + app);
6129        mProcessesOnHold.remove(app);
6130
6131        boolean badApp = false;
6132        boolean didSomething = false;
6133
6134        // See if the top visible activity is waiting to run in this process...
6135        if (normalMode) {
6136            try {
6137                if (mStackSupervisor.attachApplicationLocked(app)) {
6138                    didSomething = true;
6139                }
6140            } catch (Exception e) {
6141                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6142                badApp = true;
6143            }
6144        }
6145
6146        // Find any services that should be running in this process...
6147        if (!badApp) {
6148            try {
6149                didSomething |= mServices.attachApplicationLocked(app, processName);
6150            } catch (Exception e) {
6151                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6152                badApp = true;
6153            }
6154        }
6155
6156        // Check if a next-broadcast receiver is in this process...
6157        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6158            try {
6159                didSomething |= sendPendingBroadcastsLocked(app);
6160            } catch (Exception e) {
6161                // If the app died trying to launch the receiver we declare it 'bad'
6162                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6163                badApp = true;
6164            }
6165        }
6166
6167        // Check whether the next backup agent is in this process...
6168        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6169            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6170            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6171            try {
6172                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6173                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6174                        mBackupTarget.backupMode);
6175            } catch (Exception e) {
6176                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6177                badApp = true;
6178            }
6179        }
6180
6181        if (badApp) {
6182            app.kill("error during init", true);
6183            handleAppDiedLocked(app, false, true);
6184            return false;
6185        }
6186
6187        if (!didSomething) {
6188            updateOomAdjLocked();
6189        }
6190
6191        return true;
6192    }
6193
6194    @Override
6195    public final void attachApplication(IApplicationThread thread) {
6196        synchronized (this) {
6197            int callingPid = Binder.getCallingPid();
6198            final long origId = Binder.clearCallingIdentity();
6199            attachApplicationLocked(thread, callingPid);
6200            Binder.restoreCallingIdentity(origId);
6201        }
6202    }
6203
6204    @Override
6205    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6206        final long origId = Binder.clearCallingIdentity();
6207        synchronized (this) {
6208            ActivityStack stack = ActivityRecord.getStackLocked(token);
6209            if (stack != null) {
6210                ActivityRecord r =
6211                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6212                if (stopProfiling) {
6213                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6214                        try {
6215                            mProfileFd.close();
6216                        } catch (IOException e) {
6217                        }
6218                        clearProfilerLocked();
6219                    }
6220                }
6221            }
6222        }
6223        Binder.restoreCallingIdentity(origId);
6224    }
6225
6226    void postEnableScreenAfterBootLocked() {
6227        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6228    }
6229
6230    void enableScreenAfterBoot() {
6231        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6232                SystemClock.uptimeMillis());
6233        mWindowManager.enableScreenAfterBoot();
6234
6235        synchronized (this) {
6236            updateEventDispatchingLocked();
6237        }
6238    }
6239
6240    @Override
6241    public void showBootMessage(final CharSequence msg, final boolean always) {
6242        enforceNotIsolatedCaller("showBootMessage");
6243        mWindowManager.showBootMessage(msg, always);
6244    }
6245
6246    @Override
6247    public void keyguardWaitingForActivityDrawn() {
6248        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6249        final long token = Binder.clearCallingIdentity();
6250        try {
6251            synchronized (this) {
6252                if (DEBUG_LOCKSCREEN) logLockScreen("");
6253                mWindowManager.keyguardWaitingForActivityDrawn();
6254                if (mLockScreenShown) {
6255                    mLockScreenShown = false;
6256                    comeOutOfSleepIfNeededLocked();
6257                }
6258            }
6259        } finally {
6260            Binder.restoreCallingIdentity(token);
6261        }
6262    }
6263
6264    final void finishBooting() {
6265        synchronized (this) {
6266            if (!mBootAnimationComplete) {
6267                mCallFinishBooting = true;
6268                return;
6269            }
6270            mCallFinishBooting = false;
6271        }
6272
6273        // Register receivers to handle package update events
6274        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6275
6276        // Let system services know.
6277        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6278
6279        synchronized (this) {
6280            // Ensure that any processes we had put on hold are now started
6281            // up.
6282            final int NP = mProcessesOnHold.size();
6283            if (NP > 0) {
6284                ArrayList<ProcessRecord> procs =
6285                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6286                for (int ip=0; ip<NP; ip++) {
6287                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6288                            + procs.get(ip));
6289                    startProcessLocked(procs.get(ip), "on-hold", null);
6290                }
6291            }
6292
6293            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6294                // Start looking for apps that are abusing wake locks.
6295                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6296                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6297                // Tell anyone interested that we are done booting!
6298                SystemProperties.set("sys.boot_completed", "1");
6299                SystemProperties.set("dev.bootcomplete", "1");
6300                for (int i=0; i<mStartedUsers.size(); i++) {
6301                    UserStartedState uss = mStartedUsers.valueAt(i);
6302                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6303                        uss.mState = UserStartedState.STATE_RUNNING;
6304                        final int userId = mStartedUsers.keyAt(i);
6305                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6306                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6307                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6308                        broadcastIntentLocked(null, null, intent, null,
6309                                new IIntentReceiver.Stub() {
6310                                    @Override
6311                                    public void performReceive(Intent intent, int resultCode,
6312                                            String data, Bundle extras, boolean ordered,
6313                                            boolean sticky, int sendingUser) {
6314                                        synchronized (ActivityManagerService.this) {
6315                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6316                                                    true, false);
6317                                        }
6318                                    }
6319                                },
6320                                0, null, null,
6321                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6322                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6323                                userId);
6324                    }
6325                }
6326                scheduleStartProfilesLocked();
6327            }
6328        }
6329    }
6330
6331    @Override
6332    public void bootAnimationComplete() {
6333        final boolean callFinishBooting;
6334        synchronized (this) {
6335            callFinishBooting = mCallFinishBooting;
6336            mBootAnimationComplete = true;
6337        }
6338        if (callFinishBooting) {
6339            finishBooting();
6340        }
6341    }
6342
6343    final void ensureBootCompleted() {
6344        boolean booting;
6345        boolean enableScreen;
6346        synchronized (this) {
6347            booting = mBooting;
6348            mBooting = false;
6349            enableScreen = !mBooted;
6350            mBooted = true;
6351        }
6352
6353        if (booting) {
6354            finishBooting();
6355        }
6356
6357        if (enableScreen) {
6358            enableScreenAfterBoot();
6359        }
6360    }
6361
6362    @Override
6363    public final void activityResumed(IBinder token) {
6364        final long origId = Binder.clearCallingIdentity();
6365        synchronized(this) {
6366            ActivityStack stack = ActivityRecord.getStackLocked(token);
6367            if (stack != null) {
6368                ActivityRecord.activityResumedLocked(token);
6369            }
6370        }
6371        Binder.restoreCallingIdentity(origId);
6372    }
6373
6374    @Override
6375    public final void activityPaused(IBinder token) {
6376        final long origId = Binder.clearCallingIdentity();
6377        synchronized(this) {
6378            ActivityStack stack = ActivityRecord.getStackLocked(token);
6379            if (stack != null) {
6380                stack.activityPausedLocked(token, false);
6381            }
6382        }
6383        Binder.restoreCallingIdentity(origId);
6384    }
6385
6386    @Override
6387    public final void activityStopped(IBinder token, Bundle icicle,
6388            PersistableBundle persistentState, CharSequence description) {
6389        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6390
6391        // Refuse possible leaked file descriptors
6392        if (icicle != null && icicle.hasFileDescriptors()) {
6393            throw new IllegalArgumentException("File descriptors passed in Bundle");
6394        }
6395
6396        final long origId = Binder.clearCallingIdentity();
6397
6398        synchronized (this) {
6399            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6400            if (r != null) {
6401                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6402            }
6403        }
6404
6405        trimApplications();
6406
6407        Binder.restoreCallingIdentity(origId);
6408    }
6409
6410    @Override
6411    public final void activityDestroyed(IBinder token) {
6412        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6413        synchronized (this) {
6414            ActivityStack stack = ActivityRecord.getStackLocked(token);
6415            if (stack != null) {
6416                stack.activityDestroyedLocked(token);
6417            }
6418        }
6419    }
6420
6421    @Override
6422    public final void backgroundResourcesReleased(IBinder token) {
6423        final long origId = Binder.clearCallingIdentity();
6424        try {
6425            synchronized (this) {
6426                ActivityStack stack = ActivityRecord.getStackLocked(token);
6427                if (stack != null) {
6428                    stack.backgroundResourcesReleased(token);
6429                }
6430            }
6431        } finally {
6432            Binder.restoreCallingIdentity(origId);
6433        }
6434    }
6435
6436    @Override
6437    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6438        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6439    }
6440
6441    @Override
6442    public final void notifyEnterAnimationComplete(IBinder token) {
6443        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6444    }
6445
6446    @Override
6447    public String getCallingPackage(IBinder token) {
6448        synchronized (this) {
6449            ActivityRecord r = getCallingRecordLocked(token);
6450            return r != null ? r.info.packageName : null;
6451        }
6452    }
6453
6454    @Override
6455    public ComponentName getCallingActivity(IBinder token) {
6456        synchronized (this) {
6457            ActivityRecord r = getCallingRecordLocked(token);
6458            return r != null ? r.intent.getComponent() : null;
6459        }
6460    }
6461
6462    private ActivityRecord getCallingRecordLocked(IBinder token) {
6463        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6464        if (r == null) {
6465            return null;
6466        }
6467        return r.resultTo;
6468    }
6469
6470    @Override
6471    public ComponentName getActivityClassForToken(IBinder token) {
6472        synchronized(this) {
6473            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6474            if (r == null) {
6475                return null;
6476            }
6477            return r.intent.getComponent();
6478        }
6479    }
6480
6481    @Override
6482    public String getPackageForToken(IBinder token) {
6483        synchronized(this) {
6484            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6485            if (r == null) {
6486                return null;
6487            }
6488            return r.packageName;
6489        }
6490    }
6491
6492    @Override
6493    public IIntentSender getIntentSender(int type,
6494            String packageName, IBinder token, String resultWho,
6495            int requestCode, Intent[] intents, String[] resolvedTypes,
6496            int flags, Bundle options, int userId) {
6497        enforceNotIsolatedCaller("getIntentSender");
6498        // Refuse possible leaked file descriptors
6499        if (intents != null) {
6500            if (intents.length < 1) {
6501                throw new IllegalArgumentException("Intents array length must be >= 1");
6502            }
6503            for (int i=0; i<intents.length; i++) {
6504                Intent intent = intents[i];
6505                if (intent != null) {
6506                    if (intent.hasFileDescriptors()) {
6507                        throw new IllegalArgumentException("File descriptors passed in Intent");
6508                    }
6509                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6510                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6511                        throw new IllegalArgumentException(
6512                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6513                    }
6514                    intents[i] = new Intent(intent);
6515                }
6516            }
6517            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6518                throw new IllegalArgumentException(
6519                        "Intent array length does not match resolvedTypes length");
6520            }
6521        }
6522        if (options != null) {
6523            if (options.hasFileDescriptors()) {
6524                throw new IllegalArgumentException("File descriptors passed in options");
6525            }
6526        }
6527
6528        synchronized(this) {
6529            int callingUid = Binder.getCallingUid();
6530            int origUserId = userId;
6531            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6532                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6533                    ALLOW_NON_FULL, "getIntentSender", null);
6534            if (origUserId == UserHandle.USER_CURRENT) {
6535                // We don't want to evaluate this until the pending intent is
6536                // actually executed.  However, we do want to always do the
6537                // security checking for it above.
6538                userId = UserHandle.USER_CURRENT;
6539            }
6540            try {
6541                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6542                    int uid = AppGlobals.getPackageManager()
6543                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6544                    if (!UserHandle.isSameApp(callingUid, uid)) {
6545                        String msg = "Permission Denial: getIntentSender() from pid="
6546                            + Binder.getCallingPid()
6547                            + ", uid=" + Binder.getCallingUid()
6548                            + ", (need uid=" + uid + ")"
6549                            + " is not allowed to send as package " + packageName;
6550                        Slog.w(TAG, msg);
6551                        throw new SecurityException(msg);
6552                    }
6553                }
6554
6555                return getIntentSenderLocked(type, packageName, callingUid, userId,
6556                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6557
6558            } catch (RemoteException e) {
6559                throw new SecurityException(e);
6560            }
6561        }
6562    }
6563
6564    IIntentSender getIntentSenderLocked(int type, String packageName,
6565            int callingUid, int userId, IBinder token, String resultWho,
6566            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6567            Bundle options) {
6568        if (DEBUG_MU)
6569            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6570        ActivityRecord activity = null;
6571        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6572            activity = ActivityRecord.isInStackLocked(token);
6573            if (activity == null) {
6574                return null;
6575            }
6576            if (activity.finishing) {
6577                return null;
6578            }
6579        }
6580
6581        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6582        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6583        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6584        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6585                |PendingIntent.FLAG_UPDATE_CURRENT);
6586
6587        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6588                type, packageName, activity, resultWho,
6589                requestCode, intents, resolvedTypes, flags, options, userId);
6590        WeakReference<PendingIntentRecord> ref;
6591        ref = mIntentSenderRecords.get(key);
6592        PendingIntentRecord rec = ref != null ? ref.get() : null;
6593        if (rec != null) {
6594            if (!cancelCurrent) {
6595                if (updateCurrent) {
6596                    if (rec.key.requestIntent != null) {
6597                        rec.key.requestIntent.replaceExtras(intents != null ?
6598                                intents[intents.length - 1] : null);
6599                    }
6600                    if (intents != null) {
6601                        intents[intents.length-1] = rec.key.requestIntent;
6602                        rec.key.allIntents = intents;
6603                        rec.key.allResolvedTypes = resolvedTypes;
6604                    } else {
6605                        rec.key.allIntents = null;
6606                        rec.key.allResolvedTypes = null;
6607                    }
6608                }
6609                return rec;
6610            }
6611            rec.canceled = true;
6612            mIntentSenderRecords.remove(key);
6613        }
6614        if (noCreate) {
6615            return rec;
6616        }
6617        rec = new PendingIntentRecord(this, key, callingUid);
6618        mIntentSenderRecords.put(key, rec.ref);
6619        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6620            if (activity.pendingResults == null) {
6621                activity.pendingResults
6622                        = new HashSet<WeakReference<PendingIntentRecord>>();
6623            }
6624            activity.pendingResults.add(rec.ref);
6625        }
6626        return rec;
6627    }
6628
6629    @Override
6630    public void cancelIntentSender(IIntentSender sender) {
6631        if (!(sender instanceof PendingIntentRecord)) {
6632            return;
6633        }
6634        synchronized(this) {
6635            PendingIntentRecord rec = (PendingIntentRecord)sender;
6636            try {
6637                int uid = AppGlobals.getPackageManager()
6638                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6639                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6640                    String msg = "Permission Denial: cancelIntentSender() from pid="
6641                        + Binder.getCallingPid()
6642                        + ", uid=" + Binder.getCallingUid()
6643                        + " is not allowed to cancel packges "
6644                        + rec.key.packageName;
6645                    Slog.w(TAG, msg);
6646                    throw new SecurityException(msg);
6647                }
6648            } catch (RemoteException e) {
6649                throw new SecurityException(e);
6650            }
6651            cancelIntentSenderLocked(rec, true);
6652        }
6653    }
6654
6655    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6656        rec.canceled = true;
6657        mIntentSenderRecords.remove(rec.key);
6658        if (cleanActivity && rec.key.activity != null) {
6659            rec.key.activity.pendingResults.remove(rec.ref);
6660        }
6661    }
6662
6663    @Override
6664    public String getPackageForIntentSender(IIntentSender pendingResult) {
6665        if (!(pendingResult instanceof PendingIntentRecord)) {
6666            return null;
6667        }
6668        try {
6669            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6670            return res.key.packageName;
6671        } catch (ClassCastException e) {
6672        }
6673        return null;
6674    }
6675
6676    @Override
6677    public int getUidForIntentSender(IIntentSender sender) {
6678        if (sender instanceof PendingIntentRecord) {
6679            try {
6680                PendingIntentRecord res = (PendingIntentRecord)sender;
6681                return res.uid;
6682            } catch (ClassCastException e) {
6683            }
6684        }
6685        return -1;
6686    }
6687
6688    @Override
6689    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6690        if (!(pendingResult instanceof PendingIntentRecord)) {
6691            return false;
6692        }
6693        try {
6694            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6695            if (res.key.allIntents == null) {
6696                return false;
6697            }
6698            for (int i=0; i<res.key.allIntents.length; i++) {
6699                Intent intent = res.key.allIntents[i];
6700                if (intent.getPackage() != null && intent.getComponent() != null) {
6701                    return false;
6702                }
6703            }
6704            return true;
6705        } catch (ClassCastException e) {
6706        }
6707        return false;
6708    }
6709
6710    @Override
6711    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6712        if (!(pendingResult instanceof PendingIntentRecord)) {
6713            return false;
6714        }
6715        try {
6716            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6717            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6718                return true;
6719            }
6720            return false;
6721        } catch (ClassCastException e) {
6722        }
6723        return false;
6724    }
6725
6726    @Override
6727    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6728        if (!(pendingResult instanceof PendingIntentRecord)) {
6729            return null;
6730        }
6731        try {
6732            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6733            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6734        } catch (ClassCastException e) {
6735        }
6736        return null;
6737    }
6738
6739    @Override
6740    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6741        if (!(pendingResult instanceof PendingIntentRecord)) {
6742            return null;
6743        }
6744        try {
6745            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6746            Intent intent = res.key.requestIntent;
6747            if (intent != null) {
6748                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6749                        || res.lastTagPrefix.equals(prefix))) {
6750                    return res.lastTag;
6751                }
6752                res.lastTagPrefix = prefix;
6753                StringBuilder sb = new StringBuilder(128);
6754                if (prefix != null) {
6755                    sb.append(prefix);
6756                }
6757                if (intent.getAction() != null) {
6758                    sb.append(intent.getAction());
6759                } else if (intent.getComponent() != null) {
6760                    intent.getComponent().appendShortString(sb);
6761                } else {
6762                    sb.append("?");
6763                }
6764                return res.lastTag = sb.toString();
6765            }
6766        } catch (ClassCastException e) {
6767        }
6768        return null;
6769    }
6770
6771    @Override
6772    public void setProcessLimit(int max) {
6773        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6774                "setProcessLimit()");
6775        synchronized (this) {
6776            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6777            mProcessLimitOverride = max;
6778        }
6779        trimApplications();
6780    }
6781
6782    @Override
6783    public int getProcessLimit() {
6784        synchronized (this) {
6785            return mProcessLimitOverride;
6786        }
6787    }
6788
6789    void foregroundTokenDied(ForegroundToken token) {
6790        synchronized (ActivityManagerService.this) {
6791            synchronized (mPidsSelfLocked) {
6792                ForegroundToken cur
6793                    = mForegroundProcesses.get(token.pid);
6794                if (cur != token) {
6795                    return;
6796                }
6797                mForegroundProcesses.remove(token.pid);
6798                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6799                if (pr == null) {
6800                    return;
6801                }
6802                pr.forcingToForeground = null;
6803                updateProcessForegroundLocked(pr, false, false);
6804            }
6805            updateOomAdjLocked();
6806        }
6807    }
6808
6809    @Override
6810    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6811        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6812                "setProcessForeground()");
6813        synchronized(this) {
6814            boolean changed = false;
6815
6816            synchronized (mPidsSelfLocked) {
6817                ProcessRecord pr = mPidsSelfLocked.get(pid);
6818                if (pr == null && isForeground) {
6819                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6820                    return;
6821                }
6822                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6823                if (oldToken != null) {
6824                    oldToken.token.unlinkToDeath(oldToken, 0);
6825                    mForegroundProcesses.remove(pid);
6826                    if (pr != null) {
6827                        pr.forcingToForeground = null;
6828                    }
6829                    changed = true;
6830                }
6831                if (isForeground && token != null) {
6832                    ForegroundToken newToken = new ForegroundToken() {
6833                        @Override
6834                        public void binderDied() {
6835                            foregroundTokenDied(this);
6836                        }
6837                    };
6838                    newToken.pid = pid;
6839                    newToken.token = token;
6840                    try {
6841                        token.linkToDeath(newToken, 0);
6842                        mForegroundProcesses.put(pid, newToken);
6843                        pr.forcingToForeground = token;
6844                        changed = true;
6845                    } catch (RemoteException e) {
6846                        // If the process died while doing this, we will later
6847                        // do the cleanup with the process death link.
6848                    }
6849                }
6850            }
6851
6852            if (changed) {
6853                updateOomAdjLocked();
6854            }
6855        }
6856    }
6857
6858    // =========================================================
6859    // PERMISSIONS
6860    // =========================================================
6861
6862    static class PermissionController extends IPermissionController.Stub {
6863        ActivityManagerService mActivityManagerService;
6864        PermissionController(ActivityManagerService activityManagerService) {
6865            mActivityManagerService = activityManagerService;
6866        }
6867
6868        @Override
6869        public boolean checkPermission(String permission, int pid, int uid) {
6870            return mActivityManagerService.checkPermission(permission, pid,
6871                    uid) == PackageManager.PERMISSION_GRANTED;
6872        }
6873    }
6874
6875    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6876        @Override
6877        public int checkComponentPermission(String permission, int pid, int uid,
6878                int owningUid, boolean exported) {
6879            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6880                    owningUid, exported);
6881        }
6882
6883        @Override
6884        public Object getAMSLock() {
6885            return ActivityManagerService.this;
6886        }
6887    }
6888
6889    /**
6890     * This can be called with or without the global lock held.
6891     */
6892    int checkComponentPermission(String permission, int pid, int uid,
6893            int owningUid, boolean exported) {
6894        // We might be performing an operation on behalf of an indirect binder
6895        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6896        // client identity accordingly before proceeding.
6897        Identity tlsIdentity = sCallerIdentity.get();
6898        if (tlsIdentity != null) {
6899            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6900                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6901            uid = tlsIdentity.uid;
6902            pid = tlsIdentity.pid;
6903        }
6904
6905        if (pid == MY_PID) {
6906            return PackageManager.PERMISSION_GRANTED;
6907        }
6908
6909        return ActivityManager.checkComponentPermission(permission, uid,
6910                owningUid, exported);
6911    }
6912
6913    /**
6914     * As the only public entry point for permissions checking, this method
6915     * can enforce the semantic that requesting a check on a null global
6916     * permission is automatically denied.  (Internally a null permission
6917     * string is used when calling {@link #checkComponentPermission} in cases
6918     * when only uid-based security is needed.)
6919     *
6920     * This can be called with or without the global lock held.
6921     */
6922    @Override
6923    public int checkPermission(String permission, int pid, int uid) {
6924        if (permission == null) {
6925            return PackageManager.PERMISSION_DENIED;
6926        }
6927        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6928    }
6929
6930    /**
6931     * Binder IPC calls go through the public entry point.
6932     * This can be called with or without the global lock held.
6933     */
6934    int checkCallingPermission(String permission) {
6935        return checkPermission(permission,
6936                Binder.getCallingPid(),
6937                UserHandle.getAppId(Binder.getCallingUid()));
6938    }
6939
6940    /**
6941     * This can be called with or without the global lock held.
6942     */
6943    void enforceCallingPermission(String permission, String func) {
6944        if (checkCallingPermission(permission)
6945                == PackageManager.PERMISSION_GRANTED) {
6946            return;
6947        }
6948
6949        String msg = "Permission Denial: " + func + " from pid="
6950                + Binder.getCallingPid()
6951                + ", uid=" + Binder.getCallingUid()
6952                + " requires " + permission;
6953        Slog.w(TAG, msg);
6954        throw new SecurityException(msg);
6955    }
6956
6957    /**
6958     * Determine if UID is holding permissions required to access {@link Uri} in
6959     * the given {@link ProviderInfo}. Final permission checking is always done
6960     * in {@link ContentProvider}.
6961     */
6962    private final boolean checkHoldingPermissionsLocked(
6963            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6964        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6965                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6966        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6967            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6968                    != PERMISSION_GRANTED) {
6969                return false;
6970            }
6971        }
6972        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6973    }
6974
6975    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6976            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6977        if (pi.applicationInfo.uid == uid) {
6978            return true;
6979        } else if (!pi.exported) {
6980            return false;
6981        }
6982
6983        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6984        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6985        try {
6986            // check if target holds top-level <provider> permissions
6987            if (!readMet && pi.readPermission != null && considerUidPermissions
6988                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6989                readMet = true;
6990            }
6991            if (!writeMet && pi.writePermission != null && considerUidPermissions
6992                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6993                writeMet = true;
6994            }
6995
6996            // track if unprotected read/write is allowed; any denied
6997            // <path-permission> below removes this ability
6998            boolean allowDefaultRead = pi.readPermission == null;
6999            boolean allowDefaultWrite = pi.writePermission == null;
7000
7001            // check if target holds any <path-permission> that match uri
7002            final PathPermission[] pps = pi.pathPermissions;
7003            if (pps != null) {
7004                final String path = grantUri.uri.getPath();
7005                int i = pps.length;
7006                while (i > 0 && (!readMet || !writeMet)) {
7007                    i--;
7008                    PathPermission pp = pps[i];
7009                    if (pp.match(path)) {
7010                        if (!readMet) {
7011                            final String pprperm = pp.getReadPermission();
7012                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7013                                    + pprperm + " for " + pp.getPath()
7014                                    + ": match=" + pp.match(path)
7015                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7016                            if (pprperm != null) {
7017                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7018                                        == PERMISSION_GRANTED) {
7019                                    readMet = true;
7020                                } else {
7021                                    allowDefaultRead = false;
7022                                }
7023                            }
7024                        }
7025                        if (!writeMet) {
7026                            final String ppwperm = pp.getWritePermission();
7027                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7028                                    + ppwperm + " for " + pp.getPath()
7029                                    + ": match=" + pp.match(path)
7030                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7031                            if (ppwperm != null) {
7032                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7033                                        == PERMISSION_GRANTED) {
7034                                    writeMet = true;
7035                                } else {
7036                                    allowDefaultWrite = false;
7037                                }
7038                            }
7039                        }
7040                    }
7041                }
7042            }
7043
7044            // grant unprotected <provider> read/write, if not blocked by
7045            // <path-permission> above
7046            if (allowDefaultRead) readMet = true;
7047            if (allowDefaultWrite) writeMet = true;
7048
7049        } catch (RemoteException e) {
7050            return false;
7051        }
7052
7053        return readMet && writeMet;
7054    }
7055
7056    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7057        ProviderInfo pi = null;
7058        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7059        if (cpr != null) {
7060            pi = cpr.info;
7061        } else {
7062            try {
7063                pi = AppGlobals.getPackageManager().resolveContentProvider(
7064                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7065            } catch (RemoteException ex) {
7066            }
7067        }
7068        return pi;
7069    }
7070
7071    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7072        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7073        if (targetUris != null) {
7074            return targetUris.get(grantUri);
7075        }
7076        return null;
7077    }
7078
7079    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7080            String targetPkg, int targetUid, GrantUri grantUri) {
7081        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7082        if (targetUris == null) {
7083            targetUris = Maps.newArrayMap();
7084            mGrantedUriPermissions.put(targetUid, targetUris);
7085        }
7086
7087        UriPermission perm = targetUris.get(grantUri);
7088        if (perm == null) {
7089            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7090            targetUris.put(grantUri, perm);
7091        }
7092
7093        return perm;
7094    }
7095
7096    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7097            final int modeFlags) {
7098        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7099        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7100                : UriPermission.STRENGTH_OWNED;
7101
7102        // Root gets to do everything.
7103        if (uid == 0) {
7104            return true;
7105        }
7106
7107        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7108        if (perms == null) return false;
7109
7110        // First look for exact match
7111        final UriPermission exactPerm = perms.get(grantUri);
7112        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7113            return true;
7114        }
7115
7116        // No exact match, look for prefixes
7117        final int N = perms.size();
7118        for (int i = 0; i < N; i++) {
7119            final UriPermission perm = perms.valueAt(i);
7120            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7121                    && perm.getStrength(modeFlags) >= minStrength) {
7122                return true;
7123            }
7124        }
7125
7126        return false;
7127    }
7128
7129    /**
7130     * @param uri This uri must NOT contain an embedded userId.
7131     * @param userId The userId in which the uri is to be resolved.
7132     */
7133    @Override
7134    public int checkUriPermission(Uri uri, int pid, int uid,
7135            final int modeFlags, int userId) {
7136        enforceNotIsolatedCaller("checkUriPermission");
7137
7138        // Another redirected-binder-call permissions check as in
7139        // {@link checkComponentPermission}.
7140        Identity tlsIdentity = sCallerIdentity.get();
7141        if (tlsIdentity != null) {
7142            uid = tlsIdentity.uid;
7143            pid = tlsIdentity.pid;
7144        }
7145
7146        // Our own process gets to do everything.
7147        if (pid == MY_PID) {
7148            return PackageManager.PERMISSION_GRANTED;
7149        }
7150        synchronized (this) {
7151            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7152                    ? PackageManager.PERMISSION_GRANTED
7153                    : PackageManager.PERMISSION_DENIED;
7154        }
7155    }
7156
7157    /**
7158     * Check if the targetPkg can be granted permission to access uri by
7159     * the callingUid using the given modeFlags.  Throws a security exception
7160     * if callingUid is not allowed to do this.  Returns the uid of the target
7161     * if the URI permission grant should be performed; returns -1 if it is not
7162     * needed (for example targetPkg already has permission to access the URI).
7163     * If you already know the uid of the target, you can supply it in
7164     * lastTargetUid else set that to -1.
7165     */
7166    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7167            final int modeFlags, int lastTargetUid) {
7168        if (!Intent.isAccessUriMode(modeFlags)) {
7169            return -1;
7170        }
7171
7172        if (targetPkg != null) {
7173            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7174                    "Checking grant " + targetPkg + " permission to " + grantUri);
7175        }
7176
7177        final IPackageManager pm = AppGlobals.getPackageManager();
7178
7179        // If this is not a content: uri, we can't do anything with it.
7180        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7181            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7182                    "Can't grant URI permission for non-content URI: " + grantUri);
7183            return -1;
7184        }
7185
7186        final String authority = grantUri.uri.getAuthority();
7187        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7188        if (pi == null) {
7189            Slog.w(TAG, "No content provider found for permission check: " +
7190                    grantUri.uri.toSafeString());
7191            return -1;
7192        }
7193
7194        int targetUid = lastTargetUid;
7195        if (targetUid < 0 && targetPkg != null) {
7196            try {
7197                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7198                if (targetUid < 0) {
7199                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7200                            "Can't grant URI permission no uid for: " + targetPkg);
7201                    return -1;
7202                }
7203            } catch (RemoteException ex) {
7204                return -1;
7205            }
7206        }
7207
7208        if (targetUid >= 0) {
7209            // First...  does the target actually need this permission?
7210            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7211                // No need to grant the target this permission.
7212                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7213                        "Target " + targetPkg + " already has full permission to " + grantUri);
7214                return -1;
7215            }
7216        } else {
7217            // First...  there is no target package, so can anyone access it?
7218            boolean allowed = pi.exported;
7219            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7220                if (pi.readPermission != null) {
7221                    allowed = false;
7222                }
7223            }
7224            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7225                if (pi.writePermission != null) {
7226                    allowed = false;
7227                }
7228            }
7229            if (allowed) {
7230                return -1;
7231            }
7232        }
7233
7234        /* There is a special cross user grant if:
7235         * - The target is on another user.
7236         * - Apps on the current user can access the uri without any uid permissions.
7237         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7238         * grant uri permissions.
7239         */
7240        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7241                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7242                modeFlags, false /*without considering the uid permissions*/);
7243
7244        // Second...  is the provider allowing granting of URI permissions?
7245        if (!specialCrossUserGrant) {
7246            if (!pi.grantUriPermissions) {
7247                throw new SecurityException("Provider " + pi.packageName
7248                        + "/" + pi.name
7249                        + " does not allow granting of Uri permissions (uri "
7250                        + grantUri + ")");
7251            }
7252            if (pi.uriPermissionPatterns != null) {
7253                final int N = pi.uriPermissionPatterns.length;
7254                boolean allowed = false;
7255                for (int i=0; i<N; i++) {
7256                    if (pi.uriPermissionPatterns[i] != null
7257                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7258                        allowed = true;
7259                        break;
7260                    }
7261                }
7262                if (!allowed) {
7263                    throw new SecurityException("Provider " + pi.packageName
7264                            + "/" + pi.name
7265                            + " does not allow granting of permission to path of Uri "
7266                            + grantUri);
7267                }
7268            }
7269        }
7270
7271        // Third...  does the caller itself have permission to access
7272        // this uri?
7273        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7274            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7275                // Require they hold a strong enough Uri permission
7276                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7277                    throw new SecurityException("Uid " + callingUid
7278                            + " does not have permission to uri " + grantUri);
7279                }
7280            }
7281        }
7282        return targetUid;
7283    }
7284
7285    /**
7286     * @param uri This uri must NOT contain an embedded userId.
7287     * @param userId The userId in which the uri is to be resolved.
7288     */
7289    @Override
7290    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7291            final int modeFlags, int userId) {
7292        enforceNotIsolatedCaller("checkGrantUriPermission");
7293        synchronized(this) {
7294            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7295                    new GrantUri(userId, uri, false), modeFlags, -1);
7296        }
7297    }
7298
7299    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7300            final int modeFlags, UriPermissionOwner owner) {
7301        if (!Intent.isAccessUriMode(modeFlags)) {
7302            return;
7303        }
7304
7305        // So here we are: the caller has the assumed permission
7306        // to the uri, and the target doesn't.  Let's now give this to
7307        // the target.
7308
7309        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7310                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7311
7312        final String authority = grantUri.uri.getAuthority();
7313        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7314        if (pi == null) {
7315            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7316            return;
7317        }
7318
7319        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7320            grantUri.prefix = true;
7321        }
7322        final UriPermission perm = findOrCreateUriPermissionLocked(
7323                pi.packageName, targetPkg, targetUid, grantUri);
7324        perm.grantModes(modeFlags, owner);
7325    }
7326
7327    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7328            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7329        if (targetPkg == null) {
7330            throw new NullPointerException("targetPkg");
7331        }
7332        int targetUid;
7333        final IPackageManager pm = AppGlobals.getPackageManager();
7334        try {
7335            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7336        } catch (RemoteException ex) {
7337            return;
7338        }
7339
7340        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7341                targetUid);
7342        if (targetUid < 0) {
7343            return;
7344        }
7345
7346        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7347                owner);
7348    }
7349
7350    static class NeededUriGrants extends ArrayList<GrantUri> {
7351        final String targetPkg;
7352        final int targetUid;
7353        final int flags;
7354
7355        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7356            this.targetPkg = targetPkg;
7357            this.targetUid = targetUid;
7358            this.flags = flags;
7359        }
7360    }
7361
7362    /**
7363     * Like checkGrantUriPermissionLocked, but takes an Intent.
7364     */
7365    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7366            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7367        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7368                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7369                + " clip=" + (intent != null ? intent.getClipData() : null)
7370                + " from " + intent + "; flags=0x"
7371                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7372
7373        if (targetPkg == null) {
7374            throw new NullPointerException("targetPkg");
7375        }
7376
7377        if (intent == null) {
7378            return null;
7379        }
7380        Uri data = intent.getData();
7381        ClipData clip = intent.getClipData();
7382        if (data == null && clip == null) {
7383            return null;
7384        }
7385        // Default userId for uris in the intent (if they don't specify it themselves)
7386        int contentUserHint = intent.getContentUserHint();
7387        if (contentUserHint == UserHandle.USER_CURRENT) {
7388            contentUserHint = UserHandle.getUserId(callingUid);
7389        }
7390        final IPackageManager pm = AppGlobals.getPackageManager();
7391        int targetUid;
7392        if (needed != null) {
7393            targetUid = needed.targetUid;
7394        } else {
7395            try {
7396                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7397            } catch (RemoteException ex) {
7398                return null;
7399            }
7400            if (targetUid < 0) {
7401                if (DEBUG_URI_PERMISSION) {
7402                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7403                            + " on user " + targetUserId);
7404                }
7405                return null;
7406            }
7407        }
7408        if (data != null) {
7409            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7410            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7411                    targetUid);
7412            if (targetUid > 0) {
7413                if (needed == null) {
7414                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7415                }
7416                needed.add(grantUri);
7417            }
7418        }
7419        if (clip != null) {
7420            for (int i=0; i<clip.getItemCount(); i++) {
7421                Uri uri = clip.getItemAt(i).getUri();
7422                if (uri != null) {
7423                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7424                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7425                            targetUid);
7426                    if (targetUid > 0) {
7427                        if (needed == null) {
7428                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7429                        }
7430                        needed.add(grantUri);
7431                    }
7432                } else {
7433                    Intent clipIntent = clip.getItemAt(i).getIntent();
7434                    if (clipIntent != null) {
7435                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7436                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7437                        if (newNeeded != null) {
7438                            needed = newNeeded;
7439                        }
7440                    }
7441                }
7442            }
7443        }
7444
7445        return needed;
7446    }
7447
7448    /**
7449     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7450     */
7451    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7452            UriPermissionOwner owner) {
7453        if (needed != null) {
7454            for (int i=0; i<needed.size(); i++) {
7455                GrantUri grantUri = needed.get(i);
7456                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7457                        grantUri, needed.flags, owner);
7458            }
7459        }
7460    }
7461
7462    void grantUriPermissionFromIntentLocked(int callingUid,
7463            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7464        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7465                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7466        if (needed == null) {
7467            return;
7468        }
7469
7470        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7471    }
7472
7473    /**
7474     * @param uri This uri must NOT contain an embedded userId.
7475     * @param userId The userId in which the uri is to be resolved.
7476     */
7477    @Override
7478    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7479            final int modeFlags, int userId) {
7480        enforceNotIsolatedCaller("grantUriPermission");
7481        GrantUri grantUri = new GrantUri(userId, uri, false);
7482        synchronized(this) {
7483            final ProcessRecord r = getRecordForAppLocked(caller);
7484            if (r == null) {
7485                throw new SecurityException("Unable to find app for caller "
7486                        + caller
7487                        + " when granting permission to uri " + grantUri);
7488            }
7489            if (targetPkg == null) {
7490                throw new IllegalArgumentException("null target");
7491            }
7492            if (grantUri == null) {
7493                throw new IllegalArgumentException("null uri");
7494            }
7495
7496            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7497                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7498                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7499                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7500
7501            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7502                    UserHandle.getUserId(r.uid));
7503        }
7504    }
7505
7506    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7507        if (perm.modeFlags == 0) {
7508            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7509                    perm.targetUid);
7510            if (perms != null) {
7511                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7512                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7513
7514                perms.remove(perm.uri);
7515                if (perms.isEmpty()) {
7516                    mGrantedUriPermissions.remove(perm.targetUid);
7517                }
7518            }
7519        }
7520    }
7521
7522    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7523        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7524
7525        final IPackageManager pm = AppGlobals.getPackageManager();
7526        final String authority = grantUri.uri.getAuthority();
7527        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7528        if (pi == null) {
7529            Slog.w(TAG, "No content provider found for permission revoke: "
7530                    + grantUri.toSafeString());
7531            return;
7532        }
7533
7534        // Does the caller have this permission on the URI?
7535        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7536            // If they don't have direct access to the URI, then revoke any
7537            // ownerless URI permissions that have been granted to them.
7538            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7539            if (perms != null) {
7540                boolean persistChanged = false;
7541                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7542                    final UriPermission perm = it.next();
7543                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7544                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7545                        if (DEBUG_URI_PERMISSION)
7546                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7547                                    " permission to " + perm.uri);
7548                        persistChanged |= perm.revokeModes(
7549                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7550                        if (perm.modeFlags == 0) {
7551                            it.remove();
7552                        }
7553                    }
7554                }
7555                if (perms.isEmpty()) {
7556                    mGrantedUriPermissions.remove(callingUid);
7557                }
7558                if (persistChanged) {
7559                    schedulePersistUriGrants();
7560                }
7561            }
7562            return;
7563        }
7564
7565        boolean persistChanged = false;
7566
7567        // Go through all of the permissions and remove any that match.
7568        int N = mGrantedUriPermissions.size();
7569        for (int i = 0; i < N; i++) {
7570            final int targetUid = mGrantedUriPermissions.keyAt(i);
7571            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7572
7573            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7574                final UriPermission perm = it.next();
7575                if (perm.uri.sourceUserId == grantUri.sourceUserId
7576                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7577                    if (DEBUG_URI_PERMISSION)
7578                        Slog.v(TAG,
7579                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7580                    persistChanged |= perm.revokeModes(
7581                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7582                    if (perm.modeFlags == 0) {
7583                        it.remove();
7584                    }
7585                }
7586            }
7587
7588            if (perms.isEmpty()) {
7589                mGrantedUriPermissions.remove(targetUid);
7590                N--;
7591                i--;
7592            }
7593        }
7594
7595        if (persistChanged) {
7596            schedulePersistUriGrants();
7597        }
7598    }
7599
7600    /**
7601     * @param uri This uri must NOT contain an embedded userId.
7602     * @param userId The userId in which the uri is to be resolved.
7603     */
7604    @Override
7605    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7606            int userId) {
7607        enforceNotIsolatedCaller("revokeUriPermission");
7608        synchronized(this) {
7609            final ProcessRecord r = getRecordForAppLocked(caller);
7610            if (r == null) {
7611                throw new SecurityException("Unable to find app for caller "
7612                        + caller
7613                        + " when revoking permission to uri " + uri);
7614            }
7615            if (uri == null) {
7616                Slog.w(TAG, "revokeUriPermission: null uri");
7617                return;
7618            }
7619
7620            if (!Intent.isAccessUriMode(modeFlags)) {
7621                return;
7622            }
7623
7624            final IPackageManager pm = AppGlobals.getPackageManager();
7625            final String authority = uri.getAuthority();
7626            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7627            if (pi == null) {
7628                Slog.w(TAG, "No content provider found for permission revoke: "
7629                        + uri.toSafeString());
7630                return;
7631            }
7632
7633            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7634        }
7635    }
7636
7637    /**
7638     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7639     * given package.
7640     *
7641     * @param packageName Package name to match, or {@code null} to apply to all
7642     *            packages.
7643     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7644     *            to all users.
7645     * @param persistable If persistable grants should be removed.
7646     */
7647    private void removeUriPermissionsForPackageLocked(
7648            String packageName, int userHandle, boolean persistable) {
7649        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7650            throw new IllegalArgumentException("Must narrow by either package or user");
7651        }
7652
7653        boolean persistChanged = false;
7654
7655        int N = mGrantedUriPermissions.size();
7656        for (int i = 0; i < N; i++) {
7657            final int targetUid = mGrantedUriPermissions.keyAt(i);
7658            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7659
7660            // Only inspect grants matching user
7661            if (userHandle == UserHandle.USER_ALL
7662                    || userHandle == UserHandle.getUserId(targetUid)) {
7663                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7664                    final UriPermission perm = it.next();
7665
7666                    // Only inspect grants matching package
7667                    if (packageName == null || perm.sourcePkg.equals(packageName)
7668                            || perm.targetPkg.equals(packageName)) {
7669                        persistChanged |= perm.revokeModes(persistable
7670                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7671
7672                        // Only remove when no modes remain; any persisted grants
7673                        // will keep this alive.
7674                        if (perm.modeFlags == 0) {
7675                            it.remove();
7676                        }
7677                    }
7678                }
7679
7680                if (perms.isEmpty()) {
7681                    mGrantedUriPermissions.remove(targetUid);
7682                    N--;
7683                    i--;
7684                }
7685            }
7686        }
7687
7688        if (persistChanged) {
7689            schedulePersistUriGrants();
7690        }
7691    }
7692
7693    @Override
7694    public IBinder newUriPermissionOwner(String name) {
7695        enforceNotIsolatedCaller("newUriPermissionOwner");
7696        synchronized(this) {
7697            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7698            return owner.getExternalTokenLocked();
7699        }
7700    }
7701
7702    /**
7703     * @param uri This uri must NOT contain an embedded userId.
7704     * @param sourceUserId The userId in which the uri is to be resolved.
7705     * @param targetUserId The userId of the app that receives the grant.
7706     */
7707    @Override
7708    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7709            final int modeFlags, int sourceUserId, int targetUserId) {
7710        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7711                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7712        synchronized(this) {
7713            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7714            if (owner == null) {
7715                throw new IllegalArgumentException("Unknown owner: " + token);
7716            }
7717            if (fromUid != Binder.getCallingUid()) {
7718                if (Binder.getCallingUid() != Process.myUid()) {
7719                    // Only system code can grant URI permissions on behalf
7720                    // of other users.
7721                    throw new SecurityException("nice try");
7722                }
7723            }
7724            if (targetPkg == null) {
7725                throw new IllegalArgumentException("null target");
7726            }
7727            if (uri == null) {
7728                throw new IllegalArgumentException("null uri");
7729            }
7730
7731            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7732                    modeFlags, owner, targetUserId);
7733        }
7734    }
7735
7736    /**
7737     * @param uri This uri must NOT contain an embedded userId.
7738     * @param userId The userId in which the uri is to be resolved.
7739     */
7740    @Override
7741    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7742        synchronized(this) {
7743            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7744            if (owner == null) {
7745                throw new IllegalArgumentException("Unknown owner: " + token);
7746            }
7747
7748            if (uri == null) {
7749                owner.removeUriPermissionsLocked(mode);
7750            } else {
7751                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7752            }
7753        }
7754    }
7755
7756    private void schedulePersistUriGrants() {
7757        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7758            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7759                    10 * DateUtils.SECOND_IN_MILLIS);
7760        }
7761    }
7762
7763    private void writeGrantedUriPermissions() {
7764        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7765
7766        // Snapshot permissions so we can persist without lock
7767        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7768        synchronized (this) {
7769            final int size = mGrantedUriPermissions.size();
7770            for (int i = 0; i < size; i++) {
7771                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7772                for (UriPermission perm : perms.values()) {
7773                    if (perm.persistedModeFlags != 0) {
7774                        persist.add(perm.snapshot());
7775                    }
7776                }
7777            }
7778        }
7779
7780        FileOutputStream fos = null;
7781        try {
7782            fos = mGrantFile.startWrite();
7783
7784            XmlSerializer out = new FastXmlSerializer();
7785            out.setOutput(fos, "utf-8");
7786            out.startDocument(null, true);
7787            out.startTag(null, TAG_URI_GRANTS);
7788            for (UriPermission.Snapshot perm : persist) {
7789                out.startTag(null, TAG_URI_GRANT);
7790                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7791                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7792                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7793                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7794                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7795                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7796                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7797                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7798                out.endTag(null, TAG_URI_GRANT);
7799            }
7800            out.endTag(null, TAG_URI_GRANTS);
7801            out.endDocument();
7802
7803            mGrantFile.finishWrite(fos);
7804        } catch (IOException e) {
7805            if (fos != null) {
7806                mGrantFile.failWrite(fos);
7807            }
7808        }
7809    }
7810
7811    private void readGrantedUriPermissionsLocked() {
7812        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7813
7814        final long now = System.currentTimeMillis();
7815
7816        FileInputStream fis = null;
7817        try {
7818            fis = mGrantFile.openRead();
7819            final XmlPullParser in = Xml.newPullParser();
7820            in.setInput(fis, null);
7821
7822            int type;
7823            while ((type = in.next()) != END_DOCUMENT) {
7824                final String tag = in.getName();
7825                if (type == START_TAG) {
7826                    if (TAG_URI_GRANT.equals(tag)) {
7827                        final int sourceUserId;
7828                        final int targetUserId;
7829                        final int userHandle = readIntAttribute(in,
7830                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7831                        if (userHandle != UserHandle.USER_NULL) {
7832                            // For backwards compatibility.
7833                            sourceUserId = userHandle;
7834                            targetUserId = userHandle;
7835                        } else {
7836                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7837                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7838                        }
7839                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7840                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7841                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7842                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7843                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7844                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7845
7846                        // Sanity check that provider still belongs to source package
7847                        final ProviderInfo pi = getProviderInfoLocked(
7848                                uri.getAuthority(), sourceUserId);
7849                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7850                            int targetUid = -1;
7851                            try {
7852                                targetUid = AppGlobals.getPackageManager()
7853                                        .getPackageUid(targetPkg, targetUserId);
7854                            } catch (RemoteException e) {
7855                            }
7856                            if (targetUid != -1) {
7857                                final UriPermission perm = findOrCreateUriPermissionLocked(
7858                                        sourcePkg, targetPkg, targetUid,
7859                                        new GrantUri(sourceUserId, uri, prefix));
7860                                perm.initPersistedModes(modeFlags, createdTime);
7861                            }
7862                        } else {
7863                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7864                                    + " but instead found " + pi);
7865                        }
7866                    }
7867                }
7868            }
7869        } catch (FileNotFoundException e) {
7870            // Missing grants is okay
7871        } catch (IOException e) {
7872            Log.wtf(TAG, "Failed reading Uri grants", e);
7873        } catch (XmlPullParserException e) {
7874            Log.wtf(TAG, "Failed reading Uri grants", e);
7875        } finally {
7876            IoUtils.closeQuietly(fis);
7877        }
7878    }
7879
7880    /**
7881     * @param uri This uri must NOT contain an embedded userId.
7882     * @param userId The userId in which the uri is to be resolved.
7883     */
7884    @Override
7885    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7886        enforceNotIsolatedCaller("takePersistableUriPermission");
7887
7888        Preconditions.checkFlagsArgument(modeFlags,
7889                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7890
7891        synchronized (this) {
7892            final int callingUid = Binder.getCallingUid();
7893            boolean persistChanged = false;
7894            GrantUri grantUri = new GrantUri(userId, uri, false);
7895
7896            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7897                    new GrantUri(userId, uri, false));
7898            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7899                    new GrantUri(userId, uri, true));
7900
7901            final boolean exactValid = (exactPerm != null)
7902                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7903            final boolean prefixValid = (prefixPerm != null)
7904                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7905
7906            if (!(exactValid || prefixValid)) {
7907                throw new SecurityException("No persistable permission grants found for UID "
7908                        + callingUid + " and Uri " + grantUri.toSafeString());
7909            }
7910
7911            if (exactValid) {
7912                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7913            }
7914            if (prefixValid) {
7915                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7916            }
7917
7918            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7919
7920            if (persistChanged) {
7921                schedulePersistUriGrants();
7922            }
7923        }
7924    }
7925
7926    /**
7927     * @param uri This uri must NOT contain an embedded userId.
7928     * @param userId The userId in which the uri is to be resolved.
7929     */
7930    @Override
7931    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7932        enforceNotIsolatedCaller("releasePersistableUriPermission");
7933
7934        Preconditions.checkFlagsArgument(modeFlags,
7935                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7936
7937        synchronized (this) {
7938            final int callingUid = Binder.getCallingUid();
7939            boolean persistChanged = false;
7940
7941            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7942                    new GrantUri(userId, uri, false));
7943            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7944                    new GrantUri(userId, uri, true));
7945            if (exactPerm == null && prefixPerm == null) {
7946                throw new SecurityException("No permission grants found for UID " + callingUid
7947                        + " and Uri " + uri.toSafeString());
7948            }
7949
7950            if (exactPerm != null) {
7951                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7952                removeUriPermissionIfNeededLocked(exactPerm);
7953            }
7954            if (prefixPerm != null) {
7955                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7956                removeUriPermissionIfNeededLocked(prefixPerm);
7957            }
7958
7959            if (persistChanged) {
7960                schedulePersistUriGrants();
7961            }
7962        }
7963    }
7964
7965    /**
7966     * Prune any older {@link UriPermission} for the given UID until outstanding
7967     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7968     *
7969     * @return if any mutations occured that require persisting.
7970     */
7971    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7972        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7973        if (perms == null) return false;
7974        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7975
7976        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7977        for (UriPermission perm : perms.values()) {
7978            if (perm.persistedModeFlags != 0) {
7979                persisted.add(perm);
7980            }
7981        }
7982
7983        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7984        if (trimCount <= 0) return false;
7985
7986        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7987        for (int i = 0; i < trimCount; i++) {
7988            final UriPermission perm = persisted.get(i);
7989
7990            if (DEBUG_URI_PERMISSION) {
7991                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7992            }
7993
7994            perm.releasePersistableModes(~0);
7995            removeUriPermissionIfNeededLocked(perm);
7996        }
7997
7998        return true;
7999    }
8000
8001    @Override
8002    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8003            String packageName, boolean incoming) {
8004        enforceNotIsolatedCaller("getPersistedUriPermissions");
8005        Preconditions.checkNotNull(packageName, "packageName");
8006
8007        final int callingUid = Binder.getCallingUid();
8008        final IPackageManager pm = AppGlobals.getPackageManager();
8009        try {
8010            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8011            if (packageUid != callingUid) {
8012                throw new SecurityException(
8013                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8014            }
8015        } catch (RemoteException e) {
8016            throw new SecurityException("Failed to verify package name ownership");
8017        }
8018
8019        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8020        synchronized (this) {
8021            if (incoming) {
8022                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8023                        callingUid);
8024                if (perms == null) {
8025                    Slog.w(TAG, "No permission grants found for " + packageName);
8026                } else {
8027                    for (UriPermission perm : perms.values()) {
8028                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8029                            result.add(perm.buildPersistedPublicApiObject());
8030                        }
8031                    }
8032                }
8033            } else {
8034                final int size = mGrantedUriPermissions.size();
8035                for (int i = 0; i < size; i++) {
8036                    final ArrayMap<GrantUri, UriPermission> perms =
8037                            mGrantedUriPermissions.valueAt(i);
8038                    for (UriPermission perm : perms.values()) {
8039                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8040                            result.add(perm.buildPersistedPublicApiObject());
8041                        }
8042                    }
8043                }
8044            }
8045        }
8046        return new ParceledListSlice<android.content.UriPermission>(result);
8047    }
8048
8049    @Override
8050    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8051        synchronized (this) {
8052            ProcessRecord app =
8053                who != null ? getRecordForAppLocked(who) : null;
8054            if (app == null) return;
8055
8056            Message msg = Message.obtain();
8057            msg.what = WAIT_FOR_DEBUGGER_MSG;
8058            msg.obj = app;
8059            msg.arg1 = waiting ? 1 : 0;
8060            mHandler.sendMessage(msg);
8061        }
8062    }
8063
8064    @Override
8065    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8066        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8067        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8068        outInfo.availMem = Process.getFreeMemory();
8069        outInfo.totalMem = Process.getTotalMemory();
8070        outInfo.threshold = homeAppMem;
8071        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8072        outInfo.hiddenAppThreshold = cachedAppMem;
8073        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8074                ProcessList.SERVICE_ADJ);
8075        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8076                ProcessList.VISIBLE_APP_ADJ);
8077        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8078                ProcessList.FOREGROUND_APP_ADJ);
8079    }
8080
8081    // =========================================================
8082    // TASK MANAGEMENT
8083    // =========================================================
8084
8085    @Override
8086    public List<IAppTask> getAppTasks(String callingPackage) {
8087        int callingUid = Binder.getCallingUid();
8088        long ident = Binder.clearCallingIdentity();
8089
8090        synchronized(this) {
8091            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8092            try {
8093                if (localLOGV) Slog.v(TAG, "getAppTasks");
8094
8095                final int N = mRecentTasks.size();
8096                for (int i = 0; i < N; i++) {
8097                    TaskRecord tr = mRecentTasks.get(i);
8098                    // Skip tasks that do not match the caller.  We don't need to verify
8099                    // callingPackage, because we are also limiting to callingUid and know
8100                    // that will limit to the correct security sandbox.
8101                    if (tr.effectiveUid != callingUid) {
8102                        continue;
8103                    }
8104                    Intent intent = tr.getBaseIntent();
8105                    if (intent == null ||
8106                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8107                        continue;
8108                    }
8109                    ActivityManager.RecentTaskInfo taskInfo =
8110                            createRecentTaskInfoFromTaskRecord(tr);
8111                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8112                    list.add(taskImpl);
8113                }
8114            } finally {
8115                Binder.restoreCallingIdentity(ident);
8116            }
8117            return list;
8118        }
8119    }
8120
8121    @Override
8122    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8123        final int callingUid = Binder.getCallingUid();
8124        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8125
8126        synchronized(this) {
8127            if (localLOGV) Slog.v(
8128                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8129
8130            final boolean allowed = checkCallingPermission(
8131                    android.Manifest.permission.GET_TASKS)
8132                    == PackageManager.PERMISSION_GRANTED;
8133            if (!allowed) {
8134                Slog.w(TAG, "getTasks: caller " + callingUid
8135                        + " does not hold GET_TASKS; limiting output");
8136            }
8137
8138            // TODO: Improve with MRU list from all ActivityStacks.
8139            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8140        }
8141
8142        return list;
8143    }
8144
8145    TaskRecord getMostRecentTask() {
8146        return mRecentTasks.get(0);
8147    }
8148
8149    /**
8150     * Creates a new RecentTaskInfo from a TaskRecord.
8151     */
8152    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8153        // Update the task description to reflect any changes in the task stack
8154        tr.updateTaskDescription();
8155
8156        // Compose the recent task info
8157        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8158        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8159        rti.persistentId = tr.taskId;
8160        rti.baseIntent = new Intent(tr.getBaseIntent());
8161        rti.origActivity = tr.origActivity;
8162        rti.description = tr.lastDescription;
8163        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8164        rti.userId = tr.userId;
8165        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8166        rti.firstActiveTime = tr.firstActiveTime;
8167        rti.lastActiveTime = tr.lastActiveTime;
8168        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8169        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8170        return rti;
8171    }
8172
8173    @Override
8174    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8175        final int callingUid = Binder.getCallingUid();
8176        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8177                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8178
8179        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8180        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8181        synchronized (this) {
8182            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8183                    == PackageManager.PERMISSION_GRANTED;
8184            if (!allowed) {
8185                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8186                        + " does not hold GET_TASKS; limiting output");
8187            }
8188            final boolean detailed = checkCallingPermission(
8189                    android.Manifest.permission.GET_DETAILED_TASKS)
8190                    == PackageManager.PERMISSION_GRANTED;
8191
8192            final int N = mRecentTasks.size();
8193            ArrayList<ActivityManager.RecentTaskInfo> res
8194                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8195                            maxNum < N ? maxNum : N);
8196
8197            final Set<Integer> includedUsers;
8198            if (includeProfiles) {
8199                includedUsers = getProfileIdsLocked(userId);
8200            } else {
8201                includedUsers = new HashSet<Integer>();
8202            }
8203            includedUsers.add(Integer.valueOf(userId));
8204
8205            for (int i=0; i<N && maxNum > 0; i++) {
8206                TaskRecord tr = mRecentTasks.get(i);
8207                // Only add calling user or related users recent tasks
8208                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8209                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8210                    continue;
8211                }
8212
8213                // Return the entry if desired by the caller.  We always return
8214                // the first entry, because callers always expect this to be the
8215                // foreground app.  We may filter others if the caller has
8216                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8217                // we should exclude the entry.
8218
8219                if (i == 0
8220                        || withExcluded
8221                        || (tr.intent == null)
8222                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8223                                == 0)) {
8224                    if (!allowed) {
8225                        // If the caller doesn't have the GET_TASKS permission, then only
8226                        // allow them to see a small subset of tasks -- their own and home.
8227                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8228                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8229                            continue;
8230                        }
8231                    }
8232                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8233                        if (tr.stack != null && tr.stack.isHomeStack()) {
8234                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8235                            continue;
8236                        }
8237                    }
8238                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8239                        // Don't include auto remove tasks that are finished or finishing.
8240                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8241                                + tr);
8242                        continue;
8243                    }
8244                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8245                            && !tr.isAvailable) {
8246                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8247                        continue;
8248                    }
8249
8250                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8251                    if (!detailed) {
8252                        rti.baseIntent.replaceExtras((Bundle)null);
8253                    }
8254
8255                    res.add(rti);
8256                    maxNum--;
8257                }
8258            }
8259            return res;
8260        }
8261    }
8262
8263    private TaskRecord recentTaskForIdLocked(int id) {
8264        final int N = mRecentTasks.size();
8265            for (int i=0; i<N; i++) {
8266                TaskRecord tr = mRecentTasks.get(i);
8267                if (tr.taskId == id) {
8268                    return tr;
8269                }
8270            }
8271            return null;
8272    }
8273
8274    @Override
8275    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8276        synchronized (this) {
8277            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8278                    "getTaskThumbnail()");
8279            TaskRecord tr = recentTaskForIdLocked(id);
8280            if (tr != null) {
8281                return tr.getTaskThumbnailLocked();
8282            }
8283        }
8284        return null;
8285    }
8286
8287    @Override
8288    public int addAppTask(IBinder activityToken, Intent intent,
8289            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8290        final int callingUid = Binder.getCallingUid();
8291        final long callingIdent = Binder.clearCallingIdentity();
8292
8293        try {
8294            synchronized (this) {
8295                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8296                if (r == null) {
8297                    throw new IllegalArgumentException("Activity does not exist; token="
8298                            + activityToken);
8299                }
8300                ComponentName comp = intent.getComponent();
8301                if (comp == null) {
8302                    throw new IllegalArgumentException("Intent " + intent
8303                            + " must specify explicit component");
8304                }
8305                if (thumbnail.getWidth() != mThumbnailWidth
8306                        || thumbnail.getHeight() != mThumbnailHeight) {
8307                    throw new IllegalArgumentException("Bad thumbnail size: got "
8308                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8309                            + mThumbnailWidth + "x" + mThumbnailHeight);
8310                }
8311                if (intent.getSelector() != null) {
8312                    intent.setSelector(null);
8313                }
8314                if (intent.getSourceBounds() != null) {
8315                    intent.setSourceBounds(null);
8316                }
8317                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8318                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8319                        // The caller has added this as an auto-remove task...  that makes no
8320                        // sense, so turn off auto-remove.
8321                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8322                    }
8323                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8324                    // Must be a new task.
8325                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8326                }
8327                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8328                    mLastAddedTaskActivity = null;
8329                }
8330                ActivityInfo ainfo = mLastAddedTaskActivity;
8331                if (ainfo == null) {
8332                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8333                            comp, 0, UserHandle.getUserId(callingUid));
8334                    if (ainfo.applicationInfo.uid != callingUid) {
8335                        throw new SecurityException(
8336                                "Can't add task for another application: target uid="
8337                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8338                    }
8339                }
8340
8341                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8342                        intent, description);
8343
8344                int trimIdx = trimRecentsForTask(task, false);
8345                if (trimIdx >= 0) {
8346                    // If this would have caused a trim, then we'll abort because that
8347                    // means it would be added at the end of the list but then just removed.
8348                    return -1;
8349                }
8350
8351                final int N = mRecentTasks.size();
8352                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8353                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8354                    tr.removedFromRecents(mTaskPersister);
8355                }
8356
8357                task.inRecents = true;
8358                mRecentTasks.add(task);
8359                r.task.stack.addTask(task, false, false);
8360
8361                task.setLastThumbnail(thumbnail);
8362                task.freeLastThumbnail();
8363
8364                return task.taskId;
8365            }
8366        } finally {
8367            Binder.restoreCallingIdentity(callingIdent);
8368        }
8369    }
8370
8371    @Override
8372    public Point getAppTaskThumbnailSize() {
8373        synchronized (this) {
8374            return new Point(mThumbnailWidth,  mThumbnailHeight);
8375        }
8376    }
8377
8378    @Override
8379    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8380        synchronized (this) {
8381            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8382            if (r != null) {
8383                r.setTaskDescription(td);
8384                r.task.updateTaskDescription();
8385            }
8386        }
8387    }
8388
8389    @Override
8390    public Bitmap getTaskDescriptionIcon(String filename) {
8391        return mTaskPersister.getTaskDescriptionIcon(filename);
8392    }
8393
8394    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8395        mRecentTasks.remove(tr);
8396        tr.removedFromRecents(mTaskPersister);
8397        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8398        Intent baseIntent = new Intent(
8399                tr.intent != null ? tr.intent : tr.affinityIntent);
8400        ComponentName component = baseIntent.getComponent();
8401        if (component == null) {
8402            Slog.w(TAG, "Now component for base intent of task: " + tr);
8403            return;
8404        }
8405
8406        // Find any running services associated with this app.
8407        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8408
8409        if (killProcesses) {
8410            // Find any running processes associated with this app.
8411            final String pkg = component.getPackageName();
8412            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8413            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8414            for (int i=0; i<pmap.size(); i++) {
8415                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8416                for (int j=0; j<uids.size(); j++) {
8417                    ProcessRecord proc = uids.valueAt(j);
8418                    if (proc.userId != tr.userId) {
8419                        continue;
8420                    }
8421                    if (!proc.pkgList.containsKey(pkg)) {
8422                        continue;
8423                    }
8424                    procs.add(proc);
8425                }
8426            }
8427
8428            // Kill the running processes.
8429            for (int i=0; i<procs.size(); i++) {
8430                ProcessRecord pr = procs.get(i);
8431                if (pr == mHomeProcess) {
8432                    // Don't kill the home process along with tasks from the same package.
8433                    continue;
8434                }
8435                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8436                    pr.kill("remove task", true);
8437                } else {
8438                    pr.waitingToKill = "remove task";
8439                }
8440            }
8441        }
8442    }
8443
8444    /**
8445     * Removes the task with the specified task id.
8446     *
8447     * @param taskId Identifier of the task to be removed.
8448     * @param flags Additional operational flags.  May be 0 or
8449     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8450     * @return Returns true if the given task was found and removed.
8451     */
8452    private boolean removeTaskByIdLocked(int taskId, int flags) {
8453        TaskRecord tr = recentTaskForIdLocked(taskId);
8454        if (tr != null) {
8455            tr.removeTaskActivitiesLocked();
8456            cleanUpRemovedTaskLocked(tr, flags);
8457            if (tr.isPersistable) {
8458                notifyTaskPersisterLocked(null, true);
8459            }
8460            return true;
8461        }
8462        return false;
8463    }
8464
8465    @Override
8466    public boolean removeTask(int taskId, int flags) {
8467        synchronized (this) {
8468            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8469                    "removeTask()");
8470            long ident = Binder.clearCallingIdentity();
8471            try {
8472                return removeTaskByIdLocked(taskId, flags);
8473            } finally {
8474                Binder.restoreCallingIdentity(ident);
8475            }
8476        }
8477    }
8478
8479    /**
8480     * TODO: Add mController hook
8481     */
8482    @Override
8483    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8484        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8485                "moveTaskToFront()");
8486
8487        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8488        synchronized(this) {
8489            moveTaskToFrontLocked(taskId, flags, options);
8490        }
8491    }
8492
8493    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8494        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8495                Binder.getCallingUid(), -1, -1, "Task to front")) {
8496            ActivityOptions.abort(options);
8497            return;
8498        }
8499        final long origId = Binder.clearCallingIdentity();
8500        try {
8501            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8502            if (task == null) {
8503                return;
8504            }
8505            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8506                mStackSupervisor.showLockTaskToast();
8507                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8508                return;
8509            }
8510            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8511            if (prev != null && prev.isRecentsActivity()) {
8512                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8513            }
8514            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8515        } finally {
8516            Binder.restoreCallingIdentity(origId);
8517        }
8518        ActivityOptions.abort(options);
8519    }
8520
8521    @Override
8522    public void moveTaskToBack(int taskId) {
8523        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8524                "moveTaskToBack()");
8525
8526        synchronized(this) {
8527            TaskRecord tr = recentTaskForIdLocked(taskId);
8528            if (tr != null) {
8529                if (tr == mStackSupervisor.mLockTaskModeTask) {
8530                    mStackSupervisor.showLockTaskToast();
8531                    return;
8532                }
8533                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8534                ActivityStack stack = tr.stack;
8535                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8536                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8537                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8538                        return;
8539                    }
8540                }
8541                final long origId = Binder.clearCallingIdentity();
8542                try {
8543                    stack.moveTaskToBackLocked(taskId, null);
8544                } finally {
8545                    Binder.restoreCallingIdentity(origId);
8546                }
8547            }
8548        }
8549    }
8550
8551    /**
8552     * Moves an activity, and all of the other activities within the same task, to the bottom
8553     * of the history stack.  The activity's order within the task is unchanged.
8554     *
8555     * @param token A reference to the activity we wish to move
8556     * @param nonRoot If false then this only works if the activity is the root
8557     *                of a task; if true it will work for any activity in a task.
8558     * @return Returns true if the move completed, false if not.
8559     */
8560    @Override
8561    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8562        enforceNotIsolatedCaller("moveActivityTaskToBack");
8563        synchronized(this) {
8564            final long origId = Binder.clearCallingIdentity();
8565            try {
8566                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8567                if (taskId >= 0) {
8568                    if ((mStackSupervisor.mLockTaskModeTask != null)
8569                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8570                        mStackSupervisor.showLockTaskToast();
8571                        return false;
8572                    }
8573                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8574                }
8575            } finally {
8576                Binder.restoreCallingIdentity(origId);
8577            }
8578        }
8579        return false;
8580    }
8581
8582    @Override
8583    public void moveTaskBackwards(int task) {
8584        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8585                "moveTaskBackwards()");
8586
8587        synchronized(this) {
8588            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8589                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8590                return;
8591            }
8592            final long origId = Binder.clearCallingIdentity();
8593            moveTaskBackwardsLocked(task);
8594            Binder.restoreCallingIdentity(origId);
8595        }
8596    }
8597
8598    private final void moveTaskBackwardsLocked(int task) {
8599        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8600    }
8601
8602    @Override
8603    public IBinder getHomeActivityToken() throws RemoteException {
8604        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8605                "getHomeActivityToken()");
8606        synchronized (this) {
8607            return mStackSupervisor.getHomeActivityToken();
8608        }
8609    }
8610
8611    @Override
8612    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8613            IActivityContainerCallback callback) throws RemoteException {
8614        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8615                "createActivityContainer()");
8616        synchronized (this) {
8617            if (parentActivityToken == null) {
8618                throw new IllegalArgumentException("parent token must not be null");
8619            }
8620            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8621            if (r == null) {
8622                return null;
8623            }
8624            if (callback == null) {
8625                throw new IllegalArgumentException("callback must not be null");
8626            }
8627            return mStackSupervisor.createActivityContainer(r, callback);
8628        }
8629    }
8630
8631    @Override
8632    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8633        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8634                "deleteActivityContainer()");
8635        synchronized (this) {
8636            mStackSupervisor.deleteActivityContainer(container);
8637        }
8638    }
8639
8640    @Override
8641    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8642            throws RemoteException {
8643        synchronized (this) {
8644            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8645            if (stack != null) {
8646                return stack.mActivityContainer;
8647            }
8648            return null;
8649        }
8650    }
8651
8652    @Override
8653    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8654        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8655                "moveTaskToStack()");
8656        if (stackId == HOME_STACK_ID) {
8657            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8658                    new RuntimeException("here").fillInStackTrace());
8659        }
8660        synchronized (this) {
8661            long ident = Binder.clearCallingIdentity();
8662            try {
8663                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8664                        + stackId + " toTop=" + toTop);
8665                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8666            } finally {
8667                Binder.restoreCallingIdentity(ident);
8668            }
8669        }
8670    }
8671
8672    @Override
8673    public void resizeStack(int stackBoxId, Rect bounds) {
8674        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8675                "resizeStackBox()");
8676        long ident = Binder.clearCallingIdentity();
8677        try {
8678            mWindowManager.resizeStack(stackBoxId, bounds);
8679        } finally {
8680            Binder.restoreCallingIdentity(ident);
8681        }
8682    }
8683
8684    @Override
8685    public List<StackInfo> getAllStackInfos() {
8686        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8687                "getAllStackInfos()");
8688        long ident = Binder.clearCallingIdentity();
8689        try {
8690            synchronized (this) {
8691                return mStackSupervisor.getAllStackInfosLocked();
8692            }
8693        } finally {
8694            Binder.restoreCallingIdentity(ident);
8695        }
8696    }
8697
8698    @Override
8699    public StackInfo getStackInfo(int stackId) {
8700        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8701                "getStackInfo()");
8702        long ident = Binder.clearCallingIdentity();
8703        try {
8704            synchronized (this) {
8705                return mStackSupervisor.getStackInfoLocked(stackId);
8706            }
8707        } finally {
8708            Binder.restoreCallingIdentity(ident);
8709        }
8710    }
8711
8712    @Override
8713    public boolean isInHomeStack(int taskId) {
8714        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8715                "getStackInfo()");
8716        long ident = Binder.clearCallingIdentity();
8717        try {
8718            synchronized (this) {
8719                TaskRecord tr = recentTaskForIdLocked(taskId);
8720                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8721            }
8722        } finally {
8723            Binder.restoreCallingIdentity(ident);
8724        }
8725    }
8726
8727    @Override
8728    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8729        synchronized(this) {
8730            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8731        }
8732    }
8733
8734    private boolean isLockTaskAuthorized(String pkg) {
8735        final DevicePolicyManager dpm = (DevicePolicyManager)
8736                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8737        try {
8738            int uid = mContext.getPackageManager().getPackageUid(pkg,
8739                    Binder.getCallingUserHandle().getIdentifier());
8740            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8741        } catch (NameNotFoundException e) {
8742            return false;
8743        }
8744    }
8745
8746    void startLockTaskMode(TaskRecord task) {
8747        final String pkg;
8748        synchronized (this) {
8749            pkg = task.intent.getComponent().getPackageName();
8750        }
8751        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8752        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8753            final TaskRecord taskRecord = task;
8754            mHandler.post(new Runnable() {
8755                @Override
8756                public void run() {
8757                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8758                }
8759            });
8760            return;
8761        }
8762        long ident = Binder.clearCallingIdentity();
8763        try {
8764            synchronized (this) {
8765                // Since we lost lock on task, make sure it is still there.
8766                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8767                if (task != null) {
8768                    if (!isSystemInitiated
8769                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8770                        throw new IllegalArgumentException("Invalid task, not in foreground");
8771                    }
8772                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8773                }
8774            }
8775        } finally {
8776            Binder.restoreCallingIdentity(ident);
8777        }
8778    }
8779
8780    @Override
8781    public void startLockTaskMode(int taskId) {
8782        final TaskRecord task;
8783        long ident = Binder.clearCallingIdentity();
8784        try {
8785            synchronized (this) {
8786                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8787            }
8788        } finally {
8789            Binder.restoreCallingIdentity(ident);
8790        }
8791        if (task != null) {
8792            startLockTaskMode(task);
8793        }
8794    }
8795
8796    @Override
8797    public void startLockTaskMode(IBinder token) {
8798        final TaskRecord task;
8799        long ident = Binder.clearCallingIdentity();
8800        try {
8801            synchronized (this) {
8802                final ActivityRecord r = ActivityRecord.forToken(token);
8803                if (r == null) {
8804                    return;
8805                }
8806                task = r.task;
8807            }
8808        } finally {
8809            Binder.restoreCallingIdentity(ident);
8810        }
8811        if (task != null) {
8812            startLockTaskMode(task);
8813        }
8814    }
8815
8816    @Override
8817    public void startLockTaskModeOnCurrent() throws RemoteException {
8818        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8819                "startLockTaskModeOnCurrent");
8820        ActivityRecord r = null;
8821        synchronized (this) {
8822            r = mStackSupervisor.topRunningActivityLocked();
8823        }
8824        startLockTaskMode(r.task);
8825    }
8826
8827    @Override
8828    public void stopLockTaskMode() {
8829        // Verify that the user matches the package of the intent for the TaskRecord
8830        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8831        // and stopLockTaskMode.
8832        final int callingUid = Binder.getCallingUid();
8833        if (callingUid != Process.SYSTEM_UID) {
8834            try {
8835                String pkg =
8836                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8837                int uid = mContext.getPackageManager().getPackageUid(pkg,
8838                        Binder.getCallingUserHandle().getIdentifier());
8839                if (uid != callingUid) {
8840                    throw new SecurityException("Invalid uid, expected " + uid);
8841                }
8842            } catch (NameNotFoundException e) {
8843                Log.d(TAG, "stopLockTaskMode " + e);
8844                return;
8845            }
8846        }
8847        long ident = Binder.clearCallingIdentity();
8848        try {
8849            Log.d(TAG, "stopLockTaskMode");
8850            // Stop lock task
8851            synchronized (this) {
8852                mStackSupervisor.setLockTaskModeLocked(null, false);
8853            }
8854        } finally {
8855            Binder.restoreCallingIdentity(ident);
8856        }
8857    }
8858
8859    @Override
8860    public void stopLockTaskModeOnCurrent() throws RemoteException {
8861        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8862                "stopLockTaskModeOnCurrent");
8863        long ident = Binder.clearCallingIdentity();
8864        try {
8865            stopLockTaskMode();
8866        } finally {
8867            Binder.restoreCallingIdentity(ident);
8868        }
8869    }
8870
8871    @Override
8872    public boolean isInLockTaskMode() {
8873        synchronized (this) {
8874            return mStackSupervisor.isInLockTaskMode();
8875        }
8876    }
8877
8878    // =========================================================
8879    // CONTENT PROVIDERS
8880    // =========================================================
8881
8882    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8883        List<ProviderInfo> providers = null;
8884        try {
8885            providers = AppGlobals.getPackageManager().
8886                queryContentProviders(app.processName, app.uid,
8887                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8888        } catch (RemoteException ex) {
8889        }
8890        if (DEBUG_MU)
8891            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8892        int userId = app.userId;
8893        if (providers != null) {
8894            int N = providers.size();
8895            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8896            for (int i=0; i<N; i++) {
8897                ProviderInfo cpi =
8898                    (ProviderInfo)providers.get(i);
8899                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8900                        cpi.name, cpi.flags);
8901                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8902                    // This is a singleton provider, but a user besides the
8903                    // default user is asking to initialize a process it runs
8904                    // in...  well, no, it doesn't actually run in this process,
8905                    // it runs in the process of the default user.  Get rid of it.
8906                    providers.remove(i);
8907                    N--;
8908                    i--;
8909                    continue;
8910                }
8911
8912                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8913                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8914                if (cpr == null) {
8915                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8916                    mProviderMap.putProviderByClass(comp, cpr);
8917                }
8918                if (DEBUG_MU)
8919                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8920                app.pubProviders.put(cpi.name, cpr);
8921                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8922                    // Don't add this if it is a platform component that is marked
8923                    // to run in multiple processes, because this is actually
8924                    // part of the framework so doesn't make sense to track as a
8925                    // separate apk in the process.
8926                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8927                            mProcessStats);
8928                }
8929                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8930            }
8931        }
8932        return providers;
8933    }
8934
8935    /**
8936     * Check if {@link ProcessRecord} has a possible chance at accessing the
8937     * given {@link ProviderInfo}. Final permission checking is always done
8938     * in {@link ContentProvider}.
8939     */
8940    private final String checkContentProviderPermissionLocked(
8941            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8942        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8943        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8944        boolean checkedGrants = false;
8945        if (checkUser) {
8946            // Looking for cross-user grants before enforcing the typical cross-users permissions
8947            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8948            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8949                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8950                    return null;
8951                }
8952                checkedGrants = true;
8953            }
8954            userId = handleIncomingUser(callingPid, callingUid, userId,
8955                    false, ALLOW_NON_FULL,
8956                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8957            if (userId != tmpTargetUserId) {
8958                // When we actually went to determine the final targer user ID, this ended
8959                // up different than our initial check for the authority.  This is because
8960                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8961                // SELF.  So we need to re-check the grants again.
8962                checkedGrants = false;
8963            }
8964        }
8965        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8966                cpi.applicationInfo.uid, cpi.exported)
8967                == PackageManager.PERMISSION_GRANTED) {
8968            return null;
8969        }
8970        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8971                cpi.applicationInfo.uid, cpi.exported)
8972                == PackageManager.PERMISSION_GRANTED) {
8973            return null;
8974        }
8975
8976        PathPermission[] pps = cpi.pathPermissions;
8977        if (pps != null) {
8978            int i = pps.length;
8979            while (i > 0) {
8980                i--;
8981                PathPermission pp = pps[i];
8982                String pprperm = pp.getReadPermission();
8983                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8984                        cpi.applicationInfo.uid, cpi.exported)
8985                        == PackageManager.PERMISSION_GRANTED) {
8986                    return null;
8987                }
8988                String ppwperm = pp.getWritePermission();
8989                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8990                        cpi.applicationInfo.uid, cpi.exported)
8991                        == PackageManager.PERMISSION_GRANTED) {
8992                    return null;
8993                }
8994            }
8995        }
8996        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8997            return null;
8998        }
8999
9000        String msg;
9001        if (!cpi.exported) {
9002            msg = "Permission Denial: opening provider " + cpi.name
9003                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9004                    + ", uid=" + callingUid + ") that is not exported from uid "
9005                    + cpi.applicationInfo.uid;
9006        } else {
9007            msg = "Permission Denial: opening provider " + cpi.name
9008                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9009                    + ", uid=" + callingUid + ") requires "
9010                    + cpi.readPermission + " or " + cpi.writePermission;
9011        }
9012        Slog.w(TAG, msg);
9013        return msg;
9014    }
9015
9016    /**
9017     * Returns if the ContentProvider has granted a uri to callingUid
9018     */
9019    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9020        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9021        if (perms != null) {
9022            for (int i=perms.size()-1; i>=0; i--) {
9023                GrantUri grantUri = perms.keyAt(i);
9024                if (grantUri.sourceUserId == userId || !checkUser) {
9025                    if (matchesProvider(grantUri.uri, cpi)) {
9026                        return true;
9027                    }
9028                }
9029            }
9030        }
9031        return false;
9032    }
9033
9034    /**
9035     * Returns true if the uri authority is one of the authorities specified in the provider.
9036     */
9037    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9038        String uriAuth = uri.getAuthority();
9039        String cpiAuth = cpi.authority;
9040        if (cpiAuth.indexOf(';') == -1) {
9041            return cpiAuth.equals(uriAuth);
9042        }
9043        String[] cpiAuths = cpiAuth.split(";");
9044        int length = cpiAuths.length;
9045        for (int i = 0; i < length; i++) {
9046            if (cpiAuths[i].equals(uriAuth)) return true;
9047        }
9048        return false;
9049    }
9050
9051    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9052            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9053        if (r != null) {
9054            for (int i=0; i<r.conProviders.size(); i++) {
9055                ContentProviderConnection conn = r.conProviders.get(i);
9056                if (conn.provider == cpr) {
9057                    if (DEBUG_PROVIDER) Slog.v(TAG,
9058                            "Adding provider requested by "
9059                            + r.processName + " from process "
9060                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9061                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9062                    if (stable) {
9063                        conn.stableCount++;
9064                        conn.numStableIncs++;
9065                    } else {
9066                        conn.unstableCount++;
9067                        conn.numUnstableIncs++;
9068                    }
9069                    return conn;
9070                }
9071            }
9072            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9073            if (stable) {
9074                conn.stableCount = 1;
9075                conn.numStableIncs = 1;
9076            } else {
9077                conn.unstableCount = 1;
9078                conn.numUnstableIncs = 1;
9079            }
9080            cpr.connections.add(conn);
9081            r.conProviders.add(conn);
9082            return conn;
9083        }
9084        cpr.addExternalProcessHandleLocked(externalProcessToken);
9085        return null;
9086    }
9087
9088    boolean decProviderCountLocked(ContentProviderConnection conn,
9089            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9090        if (conn != null) {
9091            cpr = conn.provider;
9092            if (DEBUG_PROVIDER) Slog.v(TAG,
9093                    "Removing provider requested by "
9094                    + conn.client.processName + " from process "
9095                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9096                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9097            if (stable) {
9098                conn.stableCount--;
9099            } else {
9100                conn.unstableCount--;
9101            }
9102            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9103                cpr.connections.remove(conn);
9104                conn.client.conProviders.remove(conn);
9105                return true;
9106            }
9107            return false;
9108        }
9109        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9110        return false;
9111    }
9112
9113    private void checkTime(long startTime, String where) {
9114        long now = SystemClock.elapsedRealtime();
9115        if ((now-startTime) > 1000) {
9116            // If we are taking more than a second, log about it.
9117            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9118        }
9119    }
9120
9121    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9122            String name, IBinder token, boolean stable, int userId) {
9123        ContentProviderRecord cpr;
9124        ContentProviderConnection conn = null;
9125        ProviderInfo cpi = null;
9126
9127        synchronized(this) {
9128            long startTime = SystemClock.elapsedRealtime();
9129
9130            ProcessRecord r = null;
9131            if (caller != null) {
9132                r = getRecordForAppLocked(caller);
9133                if (r == null) {
9134                    throw new SecurityException(
9135                            "Unable to find app for caller " + caller
9136                          + " (pid=" + Binder.getCallingPid()
9137                          + ") when getting content provider " + name);
9138                }
9139            }
9140
9141            boolean checkCrossUser = true;
9142
9143            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9144
9145            // First check if this content provider has been published...
9146            cpr = mProviderMap.getProviderByName(name, userId);
9147            // If that didn't work, check if it exists for user 0 and then
9148            // verify that it's a singleton provider before using it.
9149            if (cpr == null && userId != UserHandle.USER_OWNER) {
9150                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9151                if (cpr != null) {
9152                    cpi = cpr.info;
9153                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9154                            cpi.name, cpi.flags)
9155                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9156                        userId = UserHandle.USER_OWNER;
9157                        checkCrossUser = false;
9158                    } else {
9159                        cpr = null;
9160                        cpi = null;
9161                    }
9162                }
9163            }
9164
9165            boolean providerRunning = cpr != null;
9166            if (providerRunning) {
9167                cpi = cpr.info;
9168                String msg;
9169                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9170                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9171                        != null) {
9172                    throw new SecurityException(msg);
9173                }
9174                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9175
9176                if (r != null && cpr.canRunHere(r)) {
9177                    // This provider has been published or is in the process
9178                    // of being published...  but it is also allowed to run
9179                    // in the caller's process, so don't make a connection
9180                    // and just let the caller instantiate its own instance.
9181                    ContentProviderHolder holder = cpr.newHolder(null);
9182                    // don't give caller the provider object, it needs
9183                    // to make its own.
9184                    holder.provider = null;
9185                    return holder;
9186                }
9187
9188                final long origId = Binder.clearCallingIdentity();
9189
9190                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9191
9192                // In this case the provider instance already exists, so we can
9193                // return it right away.
9194                conn = incProviderCountLocked(r, cpr, token, stable);
9195                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9196                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9197                        // If this is a perceptible app accessing the provider,
9198                        // make sure to count it as being accessed and thus
9199                        // back up on the LRU list.  This is good because
9200                        // content providers are often expensive to start.
9201                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9202                        updateLruProcessLocked(cpr.proc, false, null);
9203                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9204                    }
9205                }
9206
9207                if (cpr.proc != null) {
9208                    if (false) {
9209                        if (cpr.name.flattenToShortString().equals(
9210                                "com.android.providers.calendar/.CalendarProvider2")) {
9211                            Slog.v(TAG, "****************** KILLING "
9212                                + cpr.name.flattenToShortString());
9213                            Process.killProcess(cpr.proc.pid);
9214                        }
9215                    }
9216                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9217                    boolean success = updateOomAdjLocked(cpr.proc);
9218                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9219                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9220                    // NOTE: there is still a race here where a signal could be
9221                    // pending on the process even though we managed to update its
9222                    // adj level.  Not sure what to do about this, but at least
9223                    // the race is now smaller.
9224                    if (!success) {
9225                        // Uh oh...  it looks like the provider's process
9226                        // has been killed on us.  We need to wait for a new
9227                        // process to be started, and make sure its death
9228                        // doesn't kill our process.
9229                        Slog.i(TAG,
9230                                "Existing provider " + cpr.name.flattenToShortString()
9231                                + " is crashing; detaching " + r);
9232                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9233                        checkTime(startTime, "getContentProviderImpl: before appDied");
9234                        appDiedLocked(cpr.proc);
9235                        checkTime(startTime, "getContentProviderImpl: after appDied");
9236                        if (!lastRef) {
9237                            // This wasn't the last ref our process had on
9238                            // the provider...  we have now been killed, bail.
9239                            return null;
9240                        }
9241                        providerRunning = false;
9242                        conn = null;
9243                    }
9244                }
9245
9246                Binder.restoreCallingIdentity(origId);
9247            }
9248
9249            boolean singleton;
9250            if (!providerRunning) {
9251                try {
9252                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9253                    cpi = AppGlobals.getPackageManager().
9254                        resolveContentProvider(name,
9255                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9256                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9257                } catch (RemoteException ex) {
9258                }
9259                if (cpi == null) {
9260                    return null;
9261                }
9262                // If the provider is a singleton AND
9263                // (it's a call within the same user || the provider is a
9264                // privileged app)
9265                // Then allow connecting to the singleton provider
9266                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9267                        cpi.name, cpi.flags)
9268                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9269                if (singleton) {
9270                    userId = UserHandle.USER_OWNER;
9271                }
9272                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9273                checkTime(startTime, "getContentProviderImpl: got app info for user");
9274
9275                String msg;
9276                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9277                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9278                        != null) {
9279                    throw new SecurityException(msg);
9280                }
9281                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9282
9283                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9284                        && !cpi.processName.equals("system")) {
9285                    // If this content provider does not run in the system
9286                    // process, and the system is not yet ready to run other
9287                    // processes, then fail fast instead of hanging.
9288                    throw new IllegalArgumentException(
9289                            "Attempt to launch content provider before system ready");
9290                }
9291
9292                // Make sure that the user who owns this provider is started.  If not,
9293                // we don't want to allow it to run.
9294                if (mStartedUsers.get(userId) == null) {
9295                    Slog.w(TAG, "Unable to launch app "
9296                            + cpi.applicationInfo.packageName + "/"
9297                            + cpi.applicationInfo.uid + " for provider "
9298                            + name + ": user " + userId + " is stopped");
9299                    return null;
9300                }
9301
9302                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9303                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9304                cpr = mProviderMap.getProviderByClass(comp, userId);
9305                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9306                final boolean firstClass = cpr == null;
9307                if (firstClass) {
9308                    try {
9309                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9310                        ApplicationInfo ai =
9311                            AppGlobals.getPackageManager().
9312                                getApplicationInfo(
9313                                        cpi.applicationInfo.packageName,
9314                                        STOCK_PM_FLAGS, userId);
9315                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9316                        if (ai == null) {
9317                            Slog.w(TAG, "No package info for content provider "
9318                                    + cpi.name);
9319                            return null;
9320                        }
9321                        ai = getAppInfoForUser(ai, userId);
9322                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9323                    } catch (RemoteException ex) {
9324                        // pm is in same process, this will never happen.
9325                    }
9326                }
9327
9328                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9329
9330                if (r != null && cpr.canRunHere(r)) {
9331                    // If this is a multiprocess provider, then just return its
9332                    // info and allow the caller to instantiate it.  Only do
9333                    // this if the provider is the same user as the caller's
9334                    // process, or can run as root (so can be in any process).
9335                    return cpr.newHolder(null);
9336                }
9337
9338                if (DEBUG_PROVIDER) {
9339                    RuntimeException e = new RuntimeException("here");
9340                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9341                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9342                }
9343
9344                // This is single process, and our app is now connecting to it.
9345                // See if we are already in the process of launching this
9346                // provider.
9347                final int N = mLaunchingProviders.size();
9348                int i;
9349                for (i=0; i<N; i++) {
9350                    if (mLaunchingProviders.get(i) == cpr) {
9351                        break;
9352                    }
9353                }
9354
9355                // If the provider is not already being launched, then get it
9356                // started.
9357                if (i >= N) {
9358                    final long origId = Binder.clearCallingIdentity();
9359
9360                    try {
9361                        // Content provider is now in use, its package can't be stopped.
9362                        try {
9363                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9364                            AppGlobals.getPackageManager().setPackageStoppedState(
9365                                    cpr.appInfo.packageName, false, userId);
9366                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9367                        } catch (RemoteException e) {
9368                        } catch (IllegalArgumentException e) {
9369                            Slog.w(TAG, "Failed trying to unstop package "
9370                                    + cpr.appInfo.packageName + ": " + e);
9371                        }
9372
9373                        // Use existing process if already started
9374                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9375                        ProcessRecord proc = getProcessRecordLocked(
9376                                cpi.processName, cpr.appInfo.uid, false);
9377                        if (proc != null && proc.thread != null) {
9378                            if (DEBUG_PROVIDER) {
9379                                Slog.d(TAG, "Installing in existing process " + proc);
9380                            }
9381                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9382                            proc.pubProviders.put(cpi.name, cpr);
9383                            try {
9384                                proc.thread.scheduleInstallProvider(cpi);
9385                            } catch (RemoteException e) {
9386                            }
9387                        } else {
9388                            checkTime(startTime, "getContentProviderImpl: before start process");
9389                            proc = startProcessLocked(cpi.processName,
9390                                    cpr.appInfo, false, 0, "content provider",
9391                                    new ComponentName(cpi.applicationInfo.packageName,
9392                                            cpi.name), false, false, false);
9393                            checkTime(startTime, "getContentProviderImpl: after start process");
9394                            if (proc == null) {
9395                                Slog.w(TAG, "Unable to launch app "
9396                                        + cpi.applicationInfo.packageName + "/"
9397                                        + cpi.applicationInfo.uid + " for provider "
9398                                        + name + ": process is bad");
9399                                return null;
9400                            }
9401                        }
9402                        cpr.launchingApp = proc;
9403                        mLaunchingProviders.add(cpr);
9404                    } finally {
9405                        Binder.restoreCallingIdentity(origId);
9406                    }
9407                }
9408
9409                checkTime(startTime, "getContentProviderImpl: updating data structures");
9410
9411                // Make sure the provider is published (the same provider class
9412                // may be published under multiple names).
9413                if (firstClass) {
9414                    mProviderMap.putProviderByClass(comp, cpr);
9415                }
9416
9417                mProviderMap.putProviderByName(name, cpr);
9418                conn = incProviderCountLocked(r, cpr, token, stable);
9419                if (conn != null) {
9420                    conn.waiting = true;
9421                }
9422            }
9423            checkTime(startTime, "getContentProviderImpl: done!");
9424        }
9425
9426        // Wait for the provider to be published...
9427        synchronized (cpr) {
9428            while (cpr.provider == null) {
9429                if (cpr.launchingApp == null) {
9430                    Slog.w(TAG, "Unable to launch app "
9431                            + cpi.applicationInfo.packageName + "/"
9432                            + cpi.applicationInfo.uid + " for provider "
9433                            + name + ": launching app became null");
9434                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9435                            UserHandle.getUserId(cpi.applicationInfo.uid),
9436                            cpi.applicationInfo.packageName,
9437                            cpi.applicationInfo.uid, name);
9438                    return null;
9439                }
9440                try {
9441                    if (DEBUG_MU) {
9442                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9443                                + cpr.launchingApp);
9444                    }
9445                    if (conn != null) {
9446                        conn.waiting = true;
9447                    }
9448                    cpr.wait();
9449                } catch (InterruptedException ex) {
9450                } finally {
9451                    if (conn != null) {
9452                        conn.waiting = false;
9453                    }
9454                }
9455            }
9456        }
9457        return cpr != null ? cpr.newHolder(conn) : null;
9458    }
9459
9460    @Override
9461    public final ContentProviderHolder getContentProvider(
9462            IApplicationThread caller, String name, int userId, boolean stable) {
9463        enforceNotIsolatedCaller("getContentProvider");
9464        if (caller == null) {
9465            String msg = "null IApplicationThread when getting content provider "
9466                    + name;
9467            Slog.w(TAG, msg);
9468            throw new SecurityException(msg);
9469        }
9470        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9471        // with cross-user grant.
9472        return getContentProviderImpl(caller, name, null, stable, userId);
9473    }
9474
9475    public ContentProviderHolder getContentProviderExternal(
9476            String name, int userId, IBinder token) {
9477        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9478            "Do not have permission in call getContentProviderExternal()");
9479        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9480                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9481        return getContentProviderExternalUnchecked(name, token, userId);
9482    }
9483
9484    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9485            IBinder token, int userId) {
9486        return getContentProviderImpl(null, name, token, true, userId);
9487    }
9488
9489    /**
9490     * Drop a content provider from a ProcessRecord's bookkeeping
9491     */
9492    public void removeContentProvider(IBinder connection, boolean stable) {
9493        enforceNotIsolatedCaller("removeContentProvider");
9494        long ident = Binder.clearCallingIdentity();
9495        try {
9496            synchronized (this) {
9497                ContentProviderConnection conn;
9498                try {
9499                    conn = (ContentProviderConnection)connection;
9500                } catch (ClassCastException e) {
9501                    String msg ="removeContentProvider: " + connection
9502                            + " not a ContentProviderConnection";
9503                    Slog.w(TAG, msg);
9504                    throw new IllegalArgumentException(msg);
9505                }
9506                if (conn == null) {
9507                    throw new NullPointerException("connection is null");
9508                }
9509                if (decProviderCountLocked(conn, null, null, stable)) {
9510                    updateOomAdjLocked();
9511                }
9512            }
9513        } finally {
9514            Binder.restoreCallingIdentity(ident);
9515        }
9516    }
9517
9518    public void removeContentProviderExternal(String name, IBinder token) {
9519        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9520            "Do not have permission in call removeContentProviderExternal()");
9521        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9522    }
9523
9524    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9525        synchronized (this) {
9526            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9527            if(cpr == null) {
9528                //remove from mProvidersByClass
9529                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9530                return;
9531            }
9532
9533            //update content provider record entry info
9534            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9535            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9536            if (localCpr.hasExternalProcessHandles()) {
9537                if (localCpr.removeExternalProcessHandleLocked(token)) {
9538                    updateOomAdjLocked();
9539                } else {
9540                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9541                            + " with no external reference for token: "
9542                            + token + ".");
9543                }
9544            } else {
9545                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9546                        + " with no external references.");
9547            }
9548        }
9549    }
9550
9551    public final void publishContentProviders(IApplicationThread caller,
9552            List<ContentProviderHolder> providers) {
9553        if (providers == null) {
9554            return;
9555        }
9556
9557        enforceNotIsolatedCaller("publishContentProviders");
9558        synchronized (this) {
9559            final ProcessRecord r = getRecordForAppLocked(caller);
9560            if (DEBUG_MU)
9561                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9562            if (r == null) {
9563                throw new SecurityException(
9564                        "Unable to find app for caller " + caller
9565                      + " (pid=" + Binder.getCallingPid()
9566                      + ") when publishing content providers");
9567            }
9568
9569            final long origId = Binder.clearCallingIdentity();
9570
9571            final int N = providers.size();
9572            for (int i=0; i<N; i++) {
9573                ContentProviderHolder src = providers.get(i);
9574                if (src == null || src.info == null || src.provider == null) {
9575                    continue;
9576                }
9577                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9578                if (DEBUG_MU)
9579                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9580                if (dst != null) {
9581                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9582                    mProviderMap.putProviderByClass(comp, dst);
9583                    String names[] = dst.info.authority.split(";");
9584                    for (int j = 0; j < names.length; j++) {
9585                        mProviderMap.putProviderByName(names[j], dst);
9586                    }
9587
9588                    int NL = mLaunchingProviders.size();
9589                    int j;
9590                    for (j=0; j<NL; j++) {
9591                        if (mLaunchingProviders.get(j) == dst) {
9592                            mLaunchingProviders.remove(j);
9593                            j--;
9594                            NL--;
9595                        }
9596                    }
9597                    synchronized (dst) {
9598                        dst.provider = src.provider;
9599                        dst.proc = r;
9600                        dst.notifyAll();
9601                    }
9602                    updateOomAdjLocked(r);
9603                }
9604            }
9605
9606            Binder.restoreCallingIdentity(origId);
9607        }
9608    }
9609
9610    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9611        ContentProviderConnection conn;
9612        try {
9613            conn = (ContentProviderConnection)connection;
9614        } catch (ClassCastException e) {
9615            String msg ="refContentProvider: " + connection
9616                    + " not a ContentProviderConnection";
9617            Slog.w(TAG, msg);
9618            throw new IllegalArgumentException(msg);
9619        }
9620        if (conn == null) {
9621            throw new NullPointerException("connection is null");
9622        }
9623
9624        synchronized (this) {
9625            if (stable > 0) {
9626                conn.numStableIncs += stable;
9627            }
9628            stable = conn.stableCount + stable;
9629            if (stable < 0) {
9630                throw new IllegalStateException("stableCount < 0: " + stable);
9631            }
9632
9633            if (unstable > 0) {
9634                conn.numUnstableIncs += unstable;
9635            }
9636            unstable = conn.unstableCount + unstable;
9637            if (unstable < 0) {
9638                throw new IllegalStateException("unstableCount < 0: " + unstable);
9639            }
9640
9641            if ((stable+unstable) <= 0) {
9642                throw new IllegalStateException("ref counts can't go to zero here: stable="
9643                        + stable + " unstable=" + unstable);
9644            }
9645            conn.stableCount = stable;
9646            conn.unstableCount = unstable;
9647            return !conn.dead;
9648        }
9649    }
9650
9651    public void unstableProviderDied(IBinder connection) {
9652        ContentProviderConnection conn;
9653        try {
9654            conn = (ContentProviderConnection)connection;
9655        } catch (ClassCastException e) {
9656            String msg ="refContentProvider: " + connection
9657                    + " not a ContentProviderConnection";
9658            Slog.w(TAG, msg);
9659            throw new IllegalArgumentException(msg);
9660        }
9661        if (conn == null) {
9662            throw new NullPointerException("connection is null");
9663        }
9664
9665        // Safely retrieve the content provider associated with the connection.
9666        IContentProvider provider;
9667        synchronized (this) {
9668            provider = conn.provider.provider;
9669        }
9670
9671        if (provider == null) {
9672            // Um, yeah, we're way ahead of you.
9673            return;
9674        }
9675
9676        // Make sure the caller is being honest with us.
9677        if (provider.asBinder().pingBinder()) {
9678            // Er, no, still looks good to us.
9679            synchronized (this) {
9680                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9681                        + " says " + conn + " died, but we don't agree");
9682                return;
9683            }
9684        }
9685
9686        // Well look at that!  It's dead!
9687        synchronized (this) {
9688            if (conn.provider.provider != provider) {
9689                // But something changed...  good enough.
9690                return;
9691            }
9692
9693            ProcessRecord proc = conn.provider.proc;
9694            if (proc == null || proc.thread == null) {
9695                // Seems like the process is already cleaned up.
9696                return;
9697            }
9698
9699            // As far as we're concerned, this is just like receiving a
9700            // death notification...  just a bit prematurely.
9701            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9702                    + ") early provider death");
9703            final long ident = Binder.clearCallingIdentity();
9704            try {
9705                appDiedLocked(proc);
9706            } finally {
9707                Binder.restoreCallingIdentity(ident);
9708            }
9709        }
9710    }
9711
9712    @Override
9713    public void appNotRespondingViaProvider(IBinder connection) {
9714        enforceCallingPermission(
9715                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9716
9717        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9718        if (conn == null) {
9719            Slog.w(TAG, "ContentProviderConnection is null");
9720            return;
9721        }
9722
9723        final ProcessRecord host = conn.provider.proc;
9724        if (host == null) {
9725            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9726            return;
9727        }
9728
9729        final long token = Binder.clearCallingIdentity();
9730        try {
9731            appNotResponding(host, null, null, false, "ContentProvider not responding");
9732        } finally {
9733            Binder.restoreCallingIdentity(token);
9734        }
9735    }
9736
9737    public final void installSystemProviders() {
9738        List<ProviderInfo> providers;
9739        synchronized (this) {
9740            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9741            providers = generateApplicationProvidersLocked(app);
9742            if (providers != null) {
9743                for (int i=providers.size()-1; i>=0; i--) {
9744                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9745                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9746                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9747                                + ": not system .apk");
9748                        providers.remove(i);
9749                    }
9750                }
9751            }
9752        }
9753        if (providers != null) {
9754            mSystemThread.installSystemProviders(providers);
9755        }
9756
9757        mCoreSettingsObserver = new CoreSettingsObserver(this);
9758
9759        //mUsageStatsService.monitorPackages();
9760    }
9761
9762    /**
9763     * Allows apps to retrieve the MIME type of a URI.
9764     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9765     * users, then it does not need permission to access the ContentProvider.
9766     * Either, it needs cross-user uri grants.
9767     *
9768     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9769     *
9770     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9771     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9772     */
9773    public String getProviderMimeType(Uri uri, int userId) {
9774        enforceNotIsolatedCaller("getProviderMimeType");
9775        final String name = uri.getAuthority();
9776        int callingUid = Binder.getCallingUid();
9777        int callingPid = Binder.getCallingPid();
9778        long ident = 0;
9779        boolean clearedIdentity = false;
9780        userId = unsafeConvertIncomingUser(userId);
9781        if (canClearIdentity(callingPid, callingUid, userId)) {
9782            clearedIdentity = true;
9783            ident = Binder.clearCallingIdentity();
9784        }
9785        ContentProviderHolder holder = null;
9786        try {
9787            holder = getContentProviderExternalUnchecked(name, null, userId);
9788            if (holder != null) {
9789                return holder.provider.getType(uri);
9790            }
9791        } catch (RemoteException e) {
9792            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9793            return null;
9794        } finally {
9795            // We need to clear the identity to call removeContentProviderExternalUnchecked
9796            if (!clearedIdentity) {
9797                ident = Binder.clearCallingIdentity();
9798            }
9799            try {
9800                if (holder != null) {
9801                    removeContentProviderExternalUnchecked(name, null, userId);
9802                }
9803            } finally {
9804                Binder.restoreCallingIdentity(ident);
9805            }
9806        }
9807
9808        return null;
9809    }
9810
9811    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9812        if (UserHandle.getUserId(callingUid) == userId) {
9813            return true;
9814        }
9815        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9816                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9817                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9818                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9819                return true;
9820        }
9821        return false;
9822    }
9823
9824    // =========================================================
9825    // GLOBAL MANAGEMENT
9826    // =========================================================
9827
9828    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9829            boolean isolated, int isolatedUid) {
9830        String proc = customProcess != null ? customProcess : info.processName;
9831        BatteryStatsImpl.Uid.Proc ps = null;
9832        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9833        int uid = info.uid;
9834        if (isolated) {
9835            if (isolatedUid == 0) {
9836                int userId = UserHandle.getUserId(uid);
9837                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9838                while (true) {
9839                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9840                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9841                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9842                    }
9843                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9844                    mNextIsolatedProcessUid++;
9845                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9846                        // No process for this uid, use it.
9847                        break;
9848                    }
9849                    stepsLeft--;
9850                    if (stepsLeft <= 0) {
9851                        return null;
9852                    }
9853                }
9854            } else {
9855                // Special case for startIsolatedProcess (internal only), where
9856                // the uid of the isolated process is specified by the caller.
9857                uid = isolatedUid;
9858            }
9859        }
9860        return new ProcessRecord(stats, info, proc, uid);
9861    }
9862
9863    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9864            String abiOverride) {
9865        ProcessRecord app;
9866        if (!isolated) {
9867            app = getProcessRecordLocked(info.processName, info.uid, true);
9868        } else {
9869            app = null;
9870        }
9871
9872        if (app == null) {
9873            app = newProcessRecordLocked(info, null, isolated, 0);
9874            mProcessNames.put(info.processName, app.uid, app);
9875            if (isolated) {
9876                mIsolatedProcesses.put(app.uid, app);
9877            }
9878            updateLruProcessLocked(app, false, null);
9879            updateOomAdjLocked();
9880        }
9881
9882        // This package really, really can not be stopped.
9883        try {
9884            AppGlobals.getPackageManager().setPackageStoppedState(
9885                    info.packageName, false, UserHandle.getUserId(app.uid));
9886        } catch (RemoteException e) {
9887        } catch (IllegalArgumentException e) {
9888            Slog.w(TAG, "Failed trying to unstop package "
9889                    + info.packageName + ": " + e);
9890        }
9891
9892        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9893                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9894            app.persistent = true;
9895            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9896        }
9897        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9898            mPersistentStartingProcesses.add(app);
9899            startProcessLocked(app, "added application", app.processName, abiOverride,
9900                    null /* entryPoint */, null /* entryPointArgs */);
9901        }
9902
9903        return app;
9904    }
9905
9906    public void unhandledBack() {
9907        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9908                "unhandledBack()");
9909
9910        synchronized(this) {
9911            final long origId = Binder.clearCallingIdentity();
9912            try {
9913                getFocusedStack().unhandledBackLocked();
9914            } finally {
9915                Binder.restoreCallingIdentity(origId);
9916            }
9917        }
9918    }
9919
9920    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9921        enforceNotIsolatedCaller("openContentUri");
9922        final int userId = UserHandle.getCallingUserId();
9923        String name = uri.getAuthority();
9924        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9925        ParcelFileDescriptor pfd = null;
9926        if (cph != null) {
9927            // We record the binder invoker's uid in thread-local storage before
9928            // going to the content provider to open the file.  Later, in the code
9929            // that handles all permissions checks, we look for this uid and use
9930            // that rather than the Activity Manager's own uid.  The effect is that
9931            // we do the check against the caller's permissions even though it looks
9932            // to the content provider like the Activity Manager itself is making
9933            // the request.
9934            sCallerIdentity.set(new Identity(
9935                    Binder.getCallingPid(), Binder.getCallingUid()));
9936            try {
9937                pfd = cph.provider.openFile(null, uri, "r", null);
9938            } catch (FileNotFoundException e) {
9939                // do nothing; pfd will be returned null
9940            } finally {
9941                // Ensure that whatever happens, we clean up the identity state
9942                sCallerIdentity.remove();
9943            }
9944
9945            // We've got the fd now, so we're done with the provider.
9946            removeContentProviderExternalUnchecked(name, null, userId);
9947        } else {
9948            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9949        }
9950        return pfd;
9951    }
9952
9953    // Actually is sleeping or shutting down or whatever else in the future
9954    // is an inactive state.
9955    public boolean isSleepingOrShuttingDown() {
9956        return isSleeping() || mShuttingDown;
9957    }
9958
9959    public boolean isSleeping() {
9960        return mSleeping;
9961    }
9962
9963    void goingToSleep() {
9964        synchronized(this) {
9965            mWentToSleep = true;
9966            goToSleepIfNeededLocked();
9967        }
9968    }
9969
9970    void finishRunningVoiceLocked() {
9971        if (mRunningVoice) {
9972            mRunningVoice = false;
9973            goToSleepIfNeededLocked();
9974        }
9975    }
9976
9977    void goToSleepIfNeededLocked() {
9978        if (mWentToSleep && !mRunningVoice) {
9979            if (!mSleeping) {
9980                mSleeping = true;
9981                mStackSupervisor.goingToSleepLocked();
9982
9983                // Initialize the wake times of all processes.
9984                checkExcessivePowerUsageLocked(false);
9985                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9986                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9987                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9988            }
9989        }
9990    }
9991
9992    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9993        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9994            // Never persist the home stack.
9995            return;
9996        }
9997        mTaskPersister.wakeup(task, flush);
9998    }
9999
10000    @Override
10001    public boolean shutdown(int timeout) {
10002        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10003                != PackageManager.PERMISSION_GRANTED) {
10004            throw new SecurityException("Requires permission "
10005                    + android.Manifest.permission.SHUTDOWN);
10006        }
10007
10008        boolean timedout = false;
10009
10010        synchronized(this) {
10011            mShuttingDown = true;
10012            updateEventDispatchingLocked();
10013            timedout = mStackSupervisor.shutdownLocked(timeout);
10014        }
10015
10016        mAppOpsService.shutdown();
10017        if (mUsageStatsService != null) {
10018            mUsageStatsService.prepareShutdown();
10019        }
10020        mBatteryStatsService.shutdown();
10021        synchronized (this) {
10022            mProcessStats.shutdownLocked();
10023        }
10024        notifyTaskPersisterLocked(null, true);
10025
10026        return timedout;
10027    }
10028
10029    public final void activitySlept(IBinder token) {
10030        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10031
10032        final long origId = Binder.clearCallingIdentity();
10033
10034        synchronized (this) {
10035            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10036            if (r != null) {
10037                mStackSupervisor.activitySleptLocked(r);
10038            }
10039        }
10040
10041        Binder.restoreCallingIdentity(origId);
10042    }
10043
10044    void logLockScreen(String msg) {
10045        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10046                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10047                mWentToSleep + " mSleeping=" + mSleeping);
10048    }
10049
10050    private void comeOutOfSleepIfNeededLocked() {
10051        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10052            if (mSleeping) {
10053                mSleeping = false;
10054                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10055            }
10056        }
10057    }
10058
10059    void wakingUp() {
10060        synchronized(this) {
10061            mWentToSleep = false;
10062            comeOutOfSleepIfNeededLocked();
10063        }
10064    }
10065
10066    void startRunningVoiceLocked() {
10067        if (!mRunningVoice) {
10068            mRunningVoice = true;
10069            comeOutOfSleepIfNeededLocked();
10070        }
10071    }
10072
10073    private void updateEventDispatchingLocked() {
10074        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10075    }
10076
10077    public void setLockScreenShown(boolean shown) {
10078        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10079                != PackageManager.PERMISSION_GRANTED) {
10080            throw new SecurityException("Requires permission "
10081                    + android.Manifest.permission.DEVICE_POWER);
10082        }
10083
10084        synchronized(this) {
10085            long ident = Binder.clearCallingIdentity();
10086            try {
10087                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10088                mLockScreenShown = shown;
10089                comeOutOfSleepIfNeededLocked();
10090            } finally {
10091                Binder.restoreCallingIdentity(ident);
10092            }
10093        }
10094    }
10095
10096    @Override
10097    public void stopAppSwitches() {
10098        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10099                != PackageManager.PERMISSION_GRANTED) {
10100            throw new SecurityException("Requires permission "
10101                    + android.Manifest.permission.STOP_APP_SWITCHES);
10102        }
10103
10104        synchronized(this) {
10105            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10106                    + APP_SWITCH_DELAY_TIME;
10107            mDidAppSwitch = false;
10108            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10109            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10110            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10111        }
10112    }
10113
10114    public void resumeAppSwitches() {
10115        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10116                != PackageManager.PERMISSION_GRANTED) {
10117            throw new SecurityException("Requires permission "
10118                    + android.Manifest.permission.STOP_APP_SWITCHES);
10119        }
10120
10121        synchronized(this) {
10122            // Note that we don't execute any pending app switches... we will
10123            // let those wait until either the timeout, or the next start
10124            // activity request.
10125            mAppSwitchesAllowedTime = 0;
10126        }
10127    }
10128
10129    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10130            int callingPid, int callingUid, String name) {
10131        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10132            return true;
10133        }
10134
10135        int perm = checkComponentPermission(
10136                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10137                sourceUid, -1, true);
10138        if (perm == PackageManager.PERMISSION_GRANTED) {
10139            return true;
10140        }
10141
10142        // If the actual IPC caller is different from the logical source, then
10143        // also see if they are allowed to control app switches.
10144        if (callingUid != -1 && callingUid != sourceUid) {
10145            perm = checkComponentPermission(
10146                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10147                    callingUid, -1, true);
10148            if (perm == PackageManager.PERMISSION_GRANTED) {
10149                return true;
10150            }
10151        }
10152
10153        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10154        return false;
10155    }
10156
10157    public void setDebugApp(String packageName, boolean waitForDebugger,
10158            boolean persistent) {
10159        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10160                "setDebugApp()");
10161
10162        long ident = Binder.clearCallingIdentity();
10163        try {
10164            // Note that this is not really thread safe if there are multiple
10165            // callers into it at the same time, but that's not a situation we
10166            // care about.
10167            if (persistent) {
10168                final ContentResolver resolver = mContext.getContentResolver();
10169                Settings.Global.putString(
10170                    resolver, Settings.Global.DEBUG_APP,
10171                    packageName);
10172                Settings.Global.putInt(
10173                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10174                    waitForDebugger ? 1 : 0);
10175            }
10176
10177            synchronized (this) {
10178                if (!persistent) {
10179                    mOrigDebugApp = mDebugApp;
10180                    mOrigWaitForDebugger = mWaitForDebugger;
10181                }
10182                mDebugApp = packageName;
10183                mWaitForDebugger = waitForDebugger;
10184                mDebugTransient = !persistent;
10185                if (packageName != null) {
10186                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10187                            false, UserHandle.USER_ALL, "set debug app");
10188                }
10189            }
10190        } finally {
10191            Binder.restoreCallingIdentity(ident);
10192        }
10193    }
10194
10195    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10196        synchronized (this) {
10197            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10198            if (!isDebuggable) {
10199                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10200                    throw new SecurityException("Process not debuggable: " + app.packageName);
10201                }
10202            }
10203
10204            mOpenGlTraceApp = processName;
10205        }
10206    }
10207
10208    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10209        synchronized (this) {
10210            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10211            if (!isDebuggable) {
10212                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10213                    throw new SecurityException("Process not debuggable: " + app.packageName);
10214                }
10215            }
10216            mProfileApp = processName;
10217            mProfileFile = profilerInfo.profileFile;
10218            if (mProfileFd != null) {
10219                try {
10220                    mProfileFd.close();
10221                } catch (IOException e) {
10222                }
10223                mProfileFd = null;
10224            }
10225            mProfileFd = profilerInfo.profileFd;
10226            mSamplingInterval = profilerInfo.samplingInterval;
10227            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10228            mProfileType = 0;
10229        }
10230    }
10231
10232    @Override
10233    public void setAlwaysFinish(boolean enabled) {
10234        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10235                "setAlwaysFinish()");
10236
10237        Settings.Global.putInt(
10238                mContext.getContentResolver(),
10239                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10240
10241        synchronized (this) {
10242            mAlwaysFinishActivities = enabled;
10243        }
10244    }
10245
10246    @Override
10247    public void setActivityController(IActivityController controller) {
10248        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10249                "setActivityController()");
10250        synchronized (this) {
10251            mController = controller;
10252            Watchdog.getInstance().setActivityController(controller);
10253        }
10254    }
10255
10256    @Override
10257    public void setUserIsMonkey(boolean userIsMonkey) {
10258        synchronized (this) {
10259            synchronized (mPidsSelfLocked) {
10260                final int callingPid = Binder.getCallingPid();
10261                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10262                if (precessRecord == null) {
10263                    throw new SecurityException("Unknown process: " + callingPid);
10264                }
10265                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10266                    throw new SecurityException("Only an instrumentation process "
10267                            + "with a UiAutomation can call setUserIsMonkey");
10268                }
10269            }
10270            mUserIsMonkey = userIsMonkey;
10271        }
10272    }
10273
10274    @Override
10275    public boolean isUserAMonkey() {
10276        synchronized (this) {
10277            // If there is a controller also implies the user is a monkey.
10278            return (mUserIsMonkey || mController != null);
10279        }
10280    }
10281
10282    public void requestBugReport() {
10283        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10284        SystemProperties.set("ctl.start", "bugreport");
10285    }
10286
10287    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10288        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10289    }
10290
10291    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10292        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10293            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10294        }
10295        return KEY_DISPATCHING_TIMEOUT;
10296    }
10297
10298    @Override
10299    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10300        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10301                != PackageManager.PERMISSION_GRANTED) {
10302            throw new SecurityException("Requires permission "
10303                    + android.Manifest.permission.FILTER_EVENTS);
10304        }
10305        ProcessRecord proc;
10306        long timeout;
10307        synchronized (this) {
10308            synchronized (mPidsSelfLocked) {
10309                proc = mPidsSelfLocked.get(pid);
10310            }
10311            timeout = getInputDispatchingTimeoutLocked(proc);
10312        }
10313
10314        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10315            return -1;
10316        }
10317
10318        return timeout;
10319    }
10320
10321    /**
10322     * Handle input dispatching timeouts.
10323     * Returns whether input dispatching should be aborted or not.
10324     */
10325    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10326            final ActivityRecord activity, final ActivityRecord parent,
10327            final boolean aboveSystem, String reason) {
10328        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10329                != PackageManager.PERMISSION_GRANTED) {
10330            throw new SecurityException("Requires permission "
10331                    + android.Manifest.permission.FILTER_EVENTS);
10332        }
10333
10334        final String annotation;
10335        if (reason == null) {
10336            annotation = "Input dispatching timed out";
10337        } else {
10338            annotation = "Input dispatching timed out (" + reason + ")";
10339        }
10340
10341        if (proc != null) {
10342            synchronized (this) {
10343                if (proc.debugging) {
10344                    return false;
10345                }
10346
10347                if (mDidDexOpt) {
10348                    // Give more time since we were dexopting.
10349                    mDidDexOpt = false;
10350                    return false;
10351                }
10352
10353                if (proc.instrumentationClass != null) {
10354                    Bundle info = new Bundle();
10355                    info.putString("shortMsg", "keyDispatchingTimedOut");
10356                    info.putString("longMsg", annotation);
10357                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10358                    return true;
10359                }
10360            }
10361            mHandler.post(new Runnable() {
10362                @Override
10363                public void run() {
10364                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10365                }
10366            });
10367        }
10368
10369        return true;
10370    }
10371
10372    public Bundle getAssistContextExtras(int requestType) {
10373        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10374                "getAssistContextExtras()");
10375        PendingAssistExtras pae;
10376        Bundle extras = new Bundle();
10377        synchronized (this) {
10378            ActivityRecord activity = getFocusedStack().mResumedActivity;
10379            if (activity == null) {
10380                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10381                return null;
10382            }
10383            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10384            if (activity.app == null || activity.app.thread == null) {
10385                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10386                return extras;
10387            }
10388            if (activity.app.pid == Binder.getCallingPid()) {
10389                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10390                return extras;
10391            }
10392            pae = new PendingAssistExtras(activity);
10393            try {
10394                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10395                        requestType);
10396                mPendingAssistExtras.add(pae);
10397                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10398            } catch (RemoteException e) {
10399                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10400                return extras;
10401            }
10402        }
10403        synchronized (pae) {
10404            while (!pae.haveResult) {
10405                try {
10406                    pae.wait();
10407                } catch (InterruptedException e) {
10408                }
10409            }
10410            if (pae.result != null) {
10411                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10412            }
10413        }
10414        synchronized (this) {
10415            mPendingAssistExtras.remove(pae);
10416            mHandler.removeCallbacks(pae);
10417        }
10418        return extras;
10419    }
10420
10421    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10422        PendingAssistExtras pae = (PendingAssistExtras)token;
10423        synchronized (pae) {
10424            pae.result = extras;
10425            pae.haveResult = true;
10426            pae.notifyAll();
10427        }
10428    }
10429
10430    public void registerProcessObserver(IProcessObserver observer) {
10431        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10432                "registerProcessObserver()");
10433        synchronized (this) {
10434            mProcessObservers.register(observer);
10435        }
10436    }
10437
10438    @Override
10439    public void unregisterProcessObserver(IProcessObserver observer) {
10440        synchronized (this) {
10441            mProcessObservers.unregister(observer);
10442        }
10443    }
10444
10445    @Override
10446    public boolean convertFromTranslucent(IBinder token) {
10447        final long origId = Binder.clearCallingIdentity();
10448        try {
10449            synchronized (this) {
10450                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10451                if (r == null) {
10452                    return false;
10453                }
10454                final boolean translucentChanged = r.changeWindowTranslucency(true);
10455                if (translucentChanged) {
10456                    r.task.stack.releaseBackgroundResources();
10457                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10458                }
10459                mWindowManager.setAppFullscreen(token, true);
10460                return translucentChanged;
10461            }
10462        } finally {
10463            Binder.restoreCallingIdentity(origId);
10464        }
10465    }
10466
10467    @Override
10468    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10469        final long origId = Binder.clearCallingIdentity();
10470        try {
10471            synchronized (this) {
10472                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10473                if (r == null) {
10474                    return false;
10475                }
10476                int index = r.task.mActivities.lastIndexOf(r);
10477                if (index > 0) {
10478                    ActivityRecord under = r.task.mActivities.get(index - 1);
10479                    under.returningOptions = options;
10480                }
10481                final boolean translucentChanged = r.changeWindowTranslucency(false);
10482                if (translucentChanged) {
10483                    r.task.stack.convertToTranslucent(r);
10484                }
10485                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10486                mWindowManager.setAppFullscreen(token, false);
10487                return translucentChanged;
10488            }
10489        } finally {
10490            Binder.restoreCallingIdentity(origId);
10491        }
10492    }
10493
10494    @Override
10495    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10496        final long origId = Binder.clearCallingIdentity();
10497        try {
10498            synchronized (this) {
10499                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10500                if (r != null) {
10501                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10502                }
10503            }
10504            return false;
10505        } finally {
10506            Binder.restoreCallingIdentity(origId);
10507        }
10508    }
10509
10510    @Override
10511    public boolean isBackgroundVisibleBehind(IBinder token) {
10512        final long origId = Binder.clearCallingIdentity();
10513        try {
10514            synchronized (this) {
10515                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10516                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10517                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10518                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10519                return visible;
10520            }
10521        } finally {
10522            Binder.restoreCallingIdentity(origId);
10523        }
10524    }
10525
10526    @Override
10527    public ActivityOptions getActivityOptions(IBinder token) {
10528        final long origId = Binder.clearCallingIdentity();
10529        try {
10530            synchronized (this) {
10531                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10532                if (r != null) {
10533                    final ActivityOptions activityOptions = r.pendingOptions;
10534                    r.pendingOptions = null;
10535                    return activityOptions;
10536                }
10537                return null;
10538            }
10539        } finally {
10540            Binder.restoreCallingIdentity(origId);
10541        }
10542    }
10543
10544    @Override
10545    public void setImmersive(IBinder token, boolean immersive) {
10546        synchronized(this) {
10547            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10548            if (r == null) {
10549                throw new IllegalArgumentException();
10550            }
10551            r.immersive = immersive;
10552
10553            // update associated state if we're frontmost
10554            if (r == mFocusedActivity) {
10555                if (DEBUG_IMMERSIVE) {
10556                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10557                }
10558                applyUpdateLockStateLocked(r);
10559            }
10560        }
10561    }
10562
10563    @Override
10564    public boolean isImmersive(IBinder token) {
10565        synchronized (this) {
10566            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10567            if (r == null) {
10568                throw new IllegalArgumentException();
10569            }
10570            return r.immersive;
10571        }
10572    }
10573
10574    public boolean isTopActivityImmersive() {
10575        enforceNotIsolatedCaller("startActivity");
10576        synchronized (this) {
10577            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10578            return (r != null) ? r.immersive : false;
10579        }
10580    }
10581
10582    @Override
10583    public boolean isTopOfTask(IBinder token) {
10584        synchronized (this) {
10585            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10586            if (r == null) {
10587                throw new IllegalArgumentException();
10588            }
10589            return r.task.getTopActivity() == r;
10590        }
10591    }
10592
10593    public final void enterSafeMode() {
10594        synchronized(this) {
10595            // It only makes sense to do this before the system is ready
10596            // and started launching other packages.
10597            if (!mSystemReady) {
10598                try {
10599                    AppGlobals.getPackageManager().enterSafeMode();
10600                } catch (RemoteException e) {
10601                }
10602            }
10603
10604            mSafeMode = true;
10605        }
10606    }
10607
10608    public final void showSafeModeOverlay() {
10609        View v = LayoutInflater.from(mContext).inflate(
10610                com.android.internal.R.layout.safe_mode, null);
10611        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10612        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10613        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10614        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10615        lp.gravity = Gravity.BOTTOM | Gravity.START;
10616        lp.format = v.getBackground().getOpacity();
10617        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10618                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10619        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10620        ((WindowManager)mContext.getSystemService(
10621                Context.WINDOW_SERVICE)).addView(v, lp);
10622    }
10623
10624    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10625        if (!(sender instanceof PendingIntentRecord)) {
10626            return;
10627        }
10628        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10629        synchronized (stats) {
10630            if (mBatteryStatsService.isOnBattery()) {
10631                mBatteryStatsService.enforceCallingPermission();
10632                PendingIntentRecord rec = (PendingIntentRecord)sender;
10633                int MY_UID = Binder.getCallingUid();
10634                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10635                BatteryStatsImpl.Uid.Pkg pkg =
10636                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10637                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10638                pkg.incWakeupsLocked();
10639            }
10640        }
10641    }
10642
10643    public boolean killPids(int[] pids, String pReason, boolean secure) {
10644        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10645            throw new SecurityException("killPids only available to the system");
10646        }
10647        String reason = (pReason == null) ? "Unknown" : pReason;
10648        // XXX Note: don't acquire main activity lock here, because the window
10649        // manager calls in with its locks held.
10650
10651        boolean killed = false;
10652        synchronized (mPidsSelfLocked) {
10653            int[] types = new int[pids.length];
10654            int worstType = 0;
10655            for (int i=0; i<pids.length; i++) {
10656                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10657                if (proc != null) {
10658                    int type = proc.setAdj;
10659                    types[i] = type;
10660                    if (type > worstType) {
10661                        worstType = type;
10662                    }
10663                }
10664            }
10665
10666            // If the worst oom_adj is somewhere in the cached proc LRU range,
10667            // then constrain it so we will kill all cached procs.
10668            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10669                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10670                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10671            }
10672
10673            // If this is not a secure call, don't let it kill processes that
10674            // are important.
10675            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10676                worstType = ProcessList.SERVICE_ADJ;
10677            }
10678
10679            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10680            for (int i=0; i<pids.length; i++) {
10681                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10682                if (proc == null) {
10683                    continue;
10684                }
10685                int adj = proc.setAdj;
10686                if (adj >= worstType && !proc.killedByAm) {
10687                    proc.kill(reason, true);
10688                    killed = true;
10689                }
10690            }
10691        }
10692        return killed;
10693    }
10694
10695    @Override
10696    public void killUid(int uid, String reason) {
10697        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10698            throw new SecurityException("killUid only available to the system");
10699        }
10700        synchronized (this) {
10701            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10702                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10703                    reason != null ? reason : "kill uid");
10704        }
10705    }
10706
10707    @Override
10708    public boolean killProcessesBelowForeground(String reason) {
10709        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10710            throw new SecurityException("killProcessesBelowForeground() only available to system");
10711        }
10712
10713        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10714    }
10715
10716    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10717        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10718            throw new SecurityException("killProcessesBelowAdj() only available to system");
10719        }
10720
10721        boolean killed = false;
10722        synchronized (mPidsSelfLocked) {
10723            final int size = mPidsSelfLocked.size();
10724            for (int i = 0; i < size; i++) {
10725                final int pid = mPidsSelfLocked.keyAt(i);
10726                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10727                if (proc == null) continue;
10728
10729                final int adj = proc.setAdj;
10730                if (adj > belowAdj && !proc.killedByAm) {
10731                    proc.kill(reason, true);
10732                    killed = true;
10733                }
10734            }
10735        }
10736        return killed;
10737    }
10738
10739    @Override
10740    public void hang(final IBinder who, boolean allowRestart) {
10741        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10742                != PackageManager.PERMISSION_GRANTED) {
10743            throw new SecurityException("Requires permission "
10744                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10745        }
10746
10747        final IBinder.DeathRecipient death = new DeathRecipient() {
10748            @Override
10749            public void binderDied() {
10750                synchronized (this) {
10751                    notifyAll();
10752                }
10753            }
10754        };
10755
10756        try {
10757            who.linkToDeath(death, 0);
10758        } catch (RemoteException e) {
10759            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10760            return;
10761        }
10762
10763        synchronized (this) {
10764            Watchdog.getInstance().setAllowRestart(allowRestart);
10765            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10766            synchronized (death) {
10767                while (who.isBinderAlive()) {
10768                    try {
10769                        death.wait();
10770                    } catch (InterruptedException e) {
10771                    }
10772                }
10773            }
10774            Watchdog.getInstance().setAllowRestart(true);
10775        }
10776    }
10777
10778    @Override
10779    public void restart() {
10780        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10781                != PackageManager.PERMISSION_GRANTED) {
10782            throw new SecurityException("Requires permission "
10783                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10784        }
10785
10786        Log.i(TAG, "Sending shutdown broadcast...");
10787
10788        BroadcastReceiver br = new BroadcastReceiver() {
10789            @Override public void onReceive(Context context, Intent intent) {
10790                // Now the broadcast is done, finish up the low-level shutdown.
10791                Log.i(TAG, "Shutting down activity manager...");
10792                shutdown(10000);
10793                Log.i(TAG, "Shutdown complete, restarting!");
10794                Process.killProcess(Process.myPid());
10795                System.exit(10);
10796            }
10797        };
10798
10799        // First send the high-level shut down broadcast.
10800        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10801        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10802        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10803        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10804        mContext.sendOrderedBroadcastAsUser(intent,
10805                UserHandle.ALL, null, br, mHandler, 0, null, null);
10806        */
10807        br.onReceive(mContext, intent);
10808    }
10809
10810    private long getLowRamTimeSinceIdle(long now) {
10811        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10812    }
10813
10814    @Override
10815    public void performIdleMaintenance() {
10816        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10817                != PackageManager.PERMISSION_GRANTED) {
10818            throw new SecurityException("Requires permission "
10819                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10820        }
10821
10822        synchronized (this) {
10823            final long now = SystemClock.uptimeMillis();
10824            final long timeSinceLastIdle = now - mLastIdleTime;
10825            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10826            mLastIdleTime = now;
10827            mLowRamTimeSinceLastIdle = 0;
10828            if (mLowRamStartTime != 0) {
10829                mLowRamStartTime = now;
10830            }
10831
10832            StringBuilder sb = new StringBuilder(128);
10833            sb.append("Idle maintenance over ");
10834            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10835            sb.append(" low RAM for ");
10836            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10837            Slog.i(TAG, sb.toString());
10838
10839            // If at least 1/3 of our time since the last idle period has been spent
10840            // with RAM low, then we want to kill processes.
10841            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10842
10843            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10844                ProcessRecord proc = mLruProcesses.get(i);
10845                if (proc.notCachedSinceIdle) {
10846                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10847                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10848                        if (doKilling && proc.initialIdlePss != 0
10849                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10850                            proc.kill("idle maint (pss " + proc.lastPss
10851                                    + " from " + proc.initialIdlePss + ")", true);
10852                        }
10853                    }
10854                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10855                    proc.notCachedSinceIdle = true;
10856                    proc.initialIdlePss = 0;
10857                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10858                            isSleeping(), now);
10859                }
10860            }
10861
10862            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10863            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10864        }
10865    }
10866
10867    private void retrieveSettings() {
10868        final ContentResolver resolver = mContext.getContentResolver();
10869        String debugApp = Settings.Global.getString(
10870            resolver, Settings.Global.DEBUG_APP);
10871        boolean waitForDebugger = Settings.Global.getInt(
10872            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10873        boolean alwaysFinishActivities = Settings.Global.getInt(
10874            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10875        boolean forceRtl = Settings.Global.getInt(
10876                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10877        // Transfer any global setting for forcing RTL layout, into a System Property
10878        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10879
10880        Configuration configuration = new Configuration();
10881        Settings.System.getConfiguration(resolver, configuration);
10882        if (forceRtl) {
10883            // This will take care of setting the correct layout direction flags
10884            configuration.setLayoutDirection(configuration.locale);
10885        }
10886
10887        synchronized (this) {
10888            mDebugApp = mOrigDebugApp = debugApp;
10889            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10890            mAlwaysFinishActivities = alwaysFinishActivities;
10891            // This happens before any activities are started, so we can
10892            // change mConfiguration in-place.
10893            updateConfigurationLocked(configuration, null, false, true);
10894            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10895        }
10896    }
10897
10898    /** Loads resources after the current configuration has been set. */
10899    private void loadResourcesOnSystemReady() {
10900        final Resources res = mContext.getResources();
10901        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10902        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10903        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10904    }
10905
10906    public boolean testIsSystemReady() {
10907        // no need to synchronize(this) just to read & return the value
10908        return mSystemReady;
10909    }
10910
10911    private static File getCalledPreBootReceiversFile() {
10912        File dataDir = Environment.getDataDirectory();
10913        File systemDir = new File(dataDir, "system");
10914        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10915        return fname;
10916    }
10917
10918    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10919        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10920        File file = getCalledPreBootReceiversFile();
10921        FileInputStream fis = null;
10922        try {
10923            fis = new FileInputStream(file);
10924            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10925            int fvers = dis.readInt();
10926            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10927                String vers = dis.readUTF();
10928                String codename = dis.readUTF();
10929                String build = dis.readUTF();
10930                if (android.os.Build.VERSION.RELEASE.equals(vers)
10931                        && android.os.Build.VERSION.CODENAME.equals(codename)
10932                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10933                    int num = dis.readInt();
10934                    while (num > 0) {
10935                        num--;
10936                        String pkg = dis.readUTF();
10937                        String cls = dis.readUTF();
10938                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10939                    }
10940                }
10941            }
10942        } catch (FileNotFoundException e) {
10943        } catch (IOException e) {
10944            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10945        } finally {
10946            if (fis != null) {
10947                try {
10948                    fis.close();
10949                } catch (IOException e) {
10950                }
10951            }
10952        }
10953        return lastDoneReceivers;
10954    }
10955
10956    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10957        File file = getCalledPreBootReceiversFile();
10958        FileOutputStream fos = null;
10959        DataOutputStream dos = null;
10960        try {
10961            fos = new FileOutputStream(file);
10962            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10963            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10964            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10965            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10966            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10967            dos.writeInt(list.size());
10968            for (int i=0; i<list.size(); i++) {
10969                dos.writeUTF(list.get(i).getPackageName());
10970                dos.writeUTF(list.get(i).getClassName());
10971            }
10972        } catch (IOException e) {
10973            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10974            file.delete();
10975        } finally {
10976            FileUtils.sync(fos);
10977            if (dos != null) {
10978                try {
10979                    dos.close();
10980                } catch (IOException e) {
10981                    // TODO Auto-generated catch block
10982                    e.printStackTrace();
10983                }
10984            }
10985        }
10986    }
10987
10988    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10989            ArrayList<ComponentName> doneReceivers, int userId) {
10990        boolean waitingUpdate = false;
10991        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10992        List<ResolveInfo> ris = null;
10993        try {
10994            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10995                    intent, null, 0, userId);
10996        } catch (RemoteException e) {
10997        }
10998        if (ris != null) {
10999            for (int i=ris.size()-1; i>=0; i--) {
11000                if ((ris.get(i).activityInfo.applicationInfo.flags
11001                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11002                    ris.remove(i);
11003                }
11004            }
11005            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11006
11007            // For User 0, load the version number. When delivering to a new user, deliver
11008            // to all receivers.
11009            if (userId == UserHandle.USER_OWNER) {
11010                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11011                for (int i=0; i<ris.size(); i++) {
11012                    ActivityInfo ai = ris.get(i).activityInfo;
11013                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11014                    if (lastDoneReceivers.contains(comp)) {
11015                        // We already did the pre boot receiver for this app with the current
11016                        // platform version, so don't do it again...
11017                        ris.remove(i);
11018                        i--;
11019                        // ...however, do keep it as one that has been done, so we don't
11020                        // forget about it when rewriting the file of last done receivers.
11021                        doneReceivers.add(comp);
11022                    }
11023                }
11024            }
11025
11026            // If primary user, send broadcast to all available users, else just to userId
11027            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11028                    : new int[] { userId };
11029            for (int i = 0; i < ris.size(); i++) {
11030                ActivityInfo ai = ris.get(i).activityInfo;
11031                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11032                doneReceivers.add(comp);
11033                intent.setComponent(comp);
11034                for (int j=0; j<users.length; j++) {
11035                    IIntentReceiver finisher = null;
11036                    // On last receiver and user, set up a completion callback
11037                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11038                        finisher = new IIntentReceiver.Stub() {
11039                            public void performReceive(Intent intent, int resultCode,
11040                                    String data, Bundle extras, boolean ordered,
11041                                    boolean sticky, int sendingUser) {
11042                                // The raw IIntentReceiver interface is called
11043                                // with the AM lock held, so redispatch to
11044                                // execute our code without the lock.
11045                                mHandler.post(onFinishCallback);
11046                            }
11047                        };
11048                    }
11049                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11050                            + " for user " + users[j]);
11051                    broadcastIntentLocked(null, null, intent, null, finisher,
11052                            0, null, null, null, AppOpsManager.OP_NONE,
11053                            true, false, MY_PID, Process.SYSTEM_UID,
11054                            users[j]);
11055                    if (finisher != null) {
11056                        waitingUpdate = true;
11057                    }
11058                }
11059            }
11060        }
11061
11062        return waitingUpdate;
11063    }
11064
11065    public void systemReady(final Runnable goingCallback) {
11066        synchronized(this) {
11067            if (mSystemReady) {
11068                // If we're done calling all the receivers, run the next "boot phase" passed in
11069                // by the SystemServer
11070                if (goingCallback != null) {
11071                    goingCallback.run();
11072                }
11073                return;
11074            }
11075
11076            // Make sure we have the current profile info, since it is needed for
11077            // security checks.
11078            updateCurrentProfileIdsLocked();
11079
11080            if (mRecentTasks == null) {
11081                mRecentTasks = mTaskPersister.restoreTasksLocked();
11082                if (!mRecentTasks.isEmpty()) {
11083                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11084                }
11085                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11086                mTaskPersister.startPersisting();
11087            }
11088
11089            // Check to see if there are any update receivers to run.
11090            if (!mDidUpdate) {
11091                if (mWaitingUpdate) {
11092                    return;
11093                }
11094                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11095                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11096                    public void run() {
11097                        synchronized (ActivityManagerService.this) {
11098                            mDidUpdate = true;
11099                        }
11100                        writeLastDonePreBootReceivers(doneReceivers);
11101                        showBootMessage(mContext.getText(
11102                                R.string.android_upgrading_complete),
11103                                false);
11104                        systemReady(goingCallback);
11105                    }
11106                }, doneReceivers, UserHandle.USER_OWNER);
11107
11108                if (mWaitingUpdate) {
11109                    return;
11110                }
11111                mDidUpdate = true;
11112            }
11113
11114            mAppOpsService.systemReady();
11115            mSystemReady = true;
11116        }
11117
11118        ArrayList<ProcessRecord> procsToKill = null;
11119        synchronized(mPidsSelfLocked) {
11120            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11121                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11122                if (!isAllowedWhileBooting(proc.info)){
11123                    if (procsToKill == null) {
11124                        procsToKill = new ArrayList<ProcessRecord>();
11125                    }
11126                    procsToKill.add(proc);
11127                }
11128            }
11129        }
11130
11131        synchronized(this) {
11132            if (procsToKill != null) {
11133                for (int i=procsToKill.size()-1; i>=0; i--) {
11134                    ProcessRecord proc = procsToKill.get(i);
11135                    Slog.i(TAG, "Removing system update proc: " + proc);
11136                    removeProcessLocked(proc, true, false, "system update done");
11137                }
11138            }
11139
11140            // Now that we have cleaned up any update processes, we
11141            // are ready to start launching real processes and know that
11142            // we won't trample on them any more.
11143            mProcessesReady = true;
11144        }
11145
11146        Slog.i(TAG, "System now ready");
11147        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11148            SystemClock.uptimeMillis());
11149
11150        synchronized(this) {
11151            // Make sure we have no pre-ready processes sitting around.
11152
11153            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11154                ResolveInfo ri = mContext.getPackageManager()
11155                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11156                                STOCK_PM_FLAGS);
11157                CharSequence errorMsg = null;
11158                if (ri != null) {
11159                    ActivityInfo ai = ri.activityInfo;
11160                    ApplicationInfo app = ai.applicationInfo;
11161                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11162                        mTopAction = Intent.ACTION_FACTORY_TEST;
11163                        mTopData = null;
11164                        mTopComponent = new ComponentName(app.packageName,
11165                                ai.name);
11166                    } else {
11167                        errorMsg = mContext.getResources().getText(
11168                                com.android.internal.R.string.factorytest_not_system);
11169                    }
11170                } else {
11171                    errorMsg = mContext.getResources().getText(
11172                            com.android.internal.R.string.factorytest_no_action);
11173                }
11174                if (errorMsg != null) {
11175                    mTopAction = null;
11176                    mTopData = null;
11177                    mTopComponent = null;
11178                    Message msg = Message.obtain();
11179                    msg.what = SHOW_FACTORY_ERROR_MSG;
11180                    msg.getData().putCharSequence("msg", errorMsg);
11181                    mHandler.sendMessage(msg);
11182                }
11183            }
11184        }
11185
11186        retrieveSettings();
11187        loadResourcesOnSystemReady();
11188
11189        synchronized (this) {
11190            readGrantedUriPermissionsLocked();
11191        }
11192
11193        if (goingCallback != null) goingCallback.run();
11194
11195        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11196                Integer.toString(mCurrentUserId), mCurrentUserId);
11197        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11198                Integer.toString(mCurrentUserId), mCurrentUserId);
11199        mSystemServiceManager.startUser(mCurrentUserId);
11200
11201        synchronized (this) {
11202            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11203                try {
11204                    List apps = AppGlobals.getPackageManager().
11205                        getPersistentApplications(STOCK_PM_FLAGS);
11206                    if (apps != null) {
11207                        int N = apps.size();
11208                        int i;
11209                        for (i=0; i<N; i++) {
11210                            ApplicationInfo info
11211                                = (ApplicationInfo)apps.get(i);
11212                            if (info != null &&
11213                                    !info.packageName.equals("android")) {
11214                                addAppLocked(info, false, null /* ABI override */);
11215                            }
11216                        }
11217                    }
11218                } catch (RemoteException ex) {
11219                    // pm is in same process, this will never happen.
11220                }
11221            }
11222
11223            // Start up initial activity.
11224            mBooting = true;
11225
11226            try {
11227                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11228                    Message msg = Message.obtain();
11229                    msg.what = SHOW_UID_ERROR_MSG;
11230                    mHandler.sendMessage(msg);
11231                }
11232            } catch (RemoteException e) {
11233            }
11234
11235            long ident = Binder.clearCallingIdentity();
11236            try {
11237                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11238                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11239                        | Intent.FLAG_RECEIVER_FOREGROUND);
11240                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11241                broadcastIntentLocked(null, null, intent,
11242                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11243                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11244                intent = new Intent(Intent.ACTION_USER_STARTING);
11245                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11246                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11247                broadcastIntentLocked(null, null, intent,
11248                        null, new IIntentReceiver.Stub() {
11249                            @Override
11250                            public void performReceive(Intent intent, int resultCode, String data,
11251                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11252                                    throws RemoteException {
11253                            }
11254                        }, 0, null, null,
11255                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11256                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11257            } catch (Throwable t) {
11258                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11259            } finally {
11260                Binder.restoreCallingIdentity(ident);
11261            }
11262            mStackSupervisor.resumeTopActivitiesLocked();
11263            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11264        }
11265    }
11266
11267    private boolean makeAppCrashingLocked(ProcessRecord app,
11268            String shortMsg, String longMsg, String stackTrace) {
11269        app.crashing = true;
11270        app.crashingReport = generateProcessError(app,
11271                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11272        startAppProblemLocked(app);
11273        app.stopFreezingAllLocked();
11274        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11275    }
11276
11277    private void makeAppNotRespondingLocked(ProcessRecord app,
11278            String activity, String shortMsg, String longMsg) {
11279        app.notResponding = true;
11280        app.notRespondingReport = generateProcessError(app,
11281                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11282                activity, shortMsg, longMsg, null);
11283        startAppProblemLocked(app);
11284        app.stopFreezingAllLocked();
11285    }
11286
11287    /**
11288     * Generate a process error record, suitable for attachment to a ProcessRecord.
11289     *
11290     * @param app The ProcessRecord in which the error occurred.
11291     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11292     *                      ActivityManager.AppErrorStateInfo
11293     * @param activity The activity associated with the crash, if known.
11294     * @param shortMsg Short message describing the crash.
11295     * @param longMsg Long message describing the crash.
11296     * @param stackTrace Full crash stack trace, may be null.
11297     *
11298     * @return Returns a fully-formed AppErrorStateInfo record.
11299     */
11300    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11301            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11302        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11303
11304        report.condition = condition;
11305        report.processName = app.processName;
11306        report.pid = app.pid;
11307        report.uid = app.info.uid;
11308        report.tag = activity;
11309        report.shortMsg = shortMsg;
11310        report.longMsg = longMsg;
11311        report.stackTrace = stackTrace;
11312
11313        return report;
11314    }
11315
11316    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11317        synchronized (this) {
11318            app.crashing = false;
11319            app.crashingReport = null;
11320            app.notResponding = false;
11321            app.notRespondingReport = null;
11322            if (app.anrDialog == fromDialog) {
11323                app.anrDialog = null;
11324            }
11325            if (app.waitDialog == fromDialog) {
11326                app.waitDialog = null;
11327            }
11328            if (app.pid > 0 && app.pid != MY_PID) {
11329                handleAppCrashLocked(app, null, null, null);
11330                app.kill("user request after error", true);
11331            }
11332        }
11333    }
11334
11335    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11336            String stackTrace) {
11337        long now = SystemClock.uptimeMillis();
11338
11339        Long crashTime;
11340        if (!app.isolated) {
11341            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11342        } else {
11343            crashTime = null;
11344        }
11345        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11346            // This process loses!
11347            Slog.w(TAG, "Process " + app.info.processName
11348                    + " has crashed too many times: killing!");
11349            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11350                    app.userId, app.info.processName, app.uid);
11351            mStackSupervisor.handleAppCrashLocked(app);
11352            if (!app.persistent) {
11353                // We don't want to start this process again until the user
11354                // explicitly does so...  but for persistent process, we really
11355                // need to keep it running.  If a persistent process is actually
11356                // repeatedly crashing, then badness for everyone.
11357                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11358                        app.info.processName);
11359                if (!app.isolated) {
11360                    // XXX We don't have a way to mark isolated processes
11361                    // as bad, since they don't have a peristent identity.
11362                    mBadProcesses.put(app.info.processName, app.uid,
11363                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11364                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11365                }
11366                app.bad = true;
11367                app.removed = true;
11368                // Don't let services in this process be restarted and potentially
11369                // annoy the user repeatedly.  Unless it is persistent, since those
11370                // processes run critical code.
11371                removeProcessLocked(app, false, false, "crash");
11372                mStackSupervisor.resumeTopActivitiesLocked();
11373                return false;
11374            }
11375            mStackSupervisor.resumeTopActivitiesLocked();
11376        } else {
11377            mStackSupervisor.finishTopRunningActivityLocked(app);
11378        }
11379
11380        // Bump up the crash count of any services currently running in the proc.
11381        for (int i=app.services.size()-1; i>=0; i--) {
11382            // Any services running in the application need to be placed
11383            // back in the pending list.
11384            ServiceRecord sr = app.services.valueAt(i);
11385            sr.crashCount++;
11386        }
11387
11388        // If the crashing process is what we consider to be the "home process" and it has been
11389        // replaced by a third-party app, clear the package preferred activities from packages
11390        // with a home activity running in the process to prevent a repeatedly crashing app
11391        // from blocking the user to manually clear the list.
11392        final ArrayList<ActivityRecord> activities = app.activities;
11393        if (app == mHomeProcess && activities.size() > 0
11394                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11395            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11396                final ActivityRecord r = activities.get(activityNdx);
11397                if (r.isHomeActivity()) {
11398                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11399                    try {
11400                        ActivityThread.getPackageManager()
11401                                .clearPackagePreferredActivities(r.packageName);
11402                    } catch (RemoteException c) {
11403                        // pm is in same process, this will never happen.
11404                    }
11405                }
11406            }
11407        }
11408
11409        if (!app.isolated) {
11410            // XXX Can't keep track of crash times for isolated processes,
11411            // because they don't have a perisistent identity.
11412            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11413        }
11414
11415        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11416        return true;
11417    }
11418
11419    void startAppProblemLocked(ProcessRecord app) {
11420        // If this app is not running under the current user, then we
11421        // can't give it a report button because that would require
11422        // launching the report UI under a different user.
11423        app.errorReportReceiver = null;
11424
11425        for (int userId : mCurrentProfileIds) {
11426            if (app.userId == userId) {
11427                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11428                        mContext, app.info.packageName, app.info.flags);
11429            }
11430        }
11431        skipCurrentReceiverLocked(app);
11432    }
11433
11434    void skipCurrentReceiverLocked(ProcessRecord app) {
11435        for (BroadcastQueue queue : mBroadcastQueues) {
11436            queue.skipCurrentReceiverLocked(app);
11437        }
11438    }
11439
11440    /**
11441     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11442     * The application process will exit immediately after this call returns.
11443     * @param app object of the crashing app, null for the system server
11444     * @param crashInfo describing the exception
11445     */
11446    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11447        ProcessRecord r = findAppProcess(app, "Crash");
11448        final String processName = app == null ? "system_server"
11449                : (r == null ? "unknown" : r.processName);
11450
11451        handleApplicationCrashInner("crash", r, processName, crashInfo);
11452    }
11453
11454    /* Native crash reporting uses this inner version because it needs to be somewhat
11455     * decoupled from the AM-managed cleanup lifecycle
11456     */
11457    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11458            ApplicationErrorReport.CrashInfo crashInfo) {
11459        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11460                UserHandle.getUserId(Binder.getCallingUid()), processName,
11461                r == null ? -1 : r.info.flags,
11462                crashInfo.exceptionClassName,
11463                crashInfo.exceptionMessage,
11464                crashInfo.throwFileName,
11465                crashInfo.throwLineNumber);
11466
11467        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11468
11469        crashApplication(r, crashInfo);
11470    }
11471
11472    public void handleApplicationStrictModeViolation(
11473            IBinder app,
11474            int violationMask,
11475            StrictMode.ViolationInfo info) {
11476        ProcessRecord r = findAppProcess(app, "StrictMode");
11477        if (r == null) {
11478            return;
11479        }
11480
11481        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11482            Integer stackFingerprint = info.hashCode();
11483            boolean logIt = true;
11484            synchronized (mAlreadyLoggedViolatedStacks) {
11485                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11486                    logIt = false;
11487                    // TODO: sub-sample into EventLog for these, with
11488                    // the info.durationMillis?  Then we'd get
11489                    // the relative pain numbers, without logging all
11490                    // the stack traces repeatedly.  We'd want to do
11491                    // likewise in the client code, which also does
11492                    // dup suppression, before the Binder call.
11493                } else {
11494                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11495                        mAlreadyLoggedViolatedStacks.clear();
11496                    }
11497                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11498                }
11499            }
11500            if (logIt) {
11501                logStrictModeViolationToDropBox(r, info);
11502            }
11503        }
11504
11505        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11506            AppErrorResult result = new AppErrorResult();
11507            synchronized (this) {
11508                final long origId = Binder.clearCallingIdentity();
11509
11510                Message msg = Message.obtain();
11511                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11512                HashMap<String, Object> data = new HashMap<String, Object>();
11513                data.put("result", result);
11514                data.put("app", r);
11515                data.put("violationMask", violationMask);
11516                data.put("info", info);
11517                msg.obj = data;
11518                mHandler.sendMessage(msg);
11519
11520                Binder.restoreCallingIdentity(origId);
11521            }
11522            int res = result.get();
11523            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11524        }
11525    }
11526
11527    // Depending on the policy in effect, there could be a bunch of
11528    // these in quick succession so we try to batch these together to
11529    // minimize disk writes, number of dropbox entries, and maximize
11530    // compression, by having more fewer, larger records.
11531    private void logStrictModeViolationToDropBox(
11532            ProcessRecord process,
11533            StrictMode.ViolationInfo info) {
11534        if (info == null) {
11535            return;
11536        }
11537        final boolean isSystemApp = process == null ||
11538                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11539                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11540        final String processName = process == null ? "unknown" : process.processName;
11541        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11542        final DropBoxManager dbox = (DropBoxManager)
11543                mContext.getSystemService(Context.DROPBOX_SERVICE);
11544
11545        // Exit early if the dropbox isn't configured to accept this report type.
11546        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11547
11548        boolean bufferWasEmpty;
11549        boolean needsFlush;
11550        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11551        synchronized (sb) {
11552            bufferWasEmpty = sb.length() == 0;
11553            appendDropBoxProcessHeaders(process, processName, sb);
11554            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11555            sb.append("System-App: ").append(isSystemApp).append("\n");
11556            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11557            if (info.violationNumThisLoop != 0) {
11558                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11559            }
11560            if (info.numAnimationsRunning != 0) {
11561                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11562            }
11563            if (info.broadcastIntentAction != null) {
11564                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11565            }
11566            if (info.durationMillis != -1) {
11567                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11568            }
11569            if (info.numInstances != -1) {
11570                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11571            }
11572            if (info.tags != null) {
11573                for (String tag : info.tags) {
11574                    sb.append("Span-Tag: ").append(tag).append("\n");
11575                }
11576            }
11577            sb.append("\n");
11578            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11579                sb.append(info.crashInfo.stackTrace);
11580            }
11581            sb.append("\n");
11582
11583            // Only buffer up to ~64k.  Various logging bits truncate
11584            // things at 128k.
11585            needsFlush = (sb.length() > 64 * 1024);
11586        }
11587
11588        // Flush immediately if the buffer's grown too large, or this
11589        // is a non-system app.  Non-system apps are isolated with a
11590        // different tag & policy and not batched.
11591        //
11592        // Batching is useful during internal testing with
11593        // StrictMode settings turned up high.  Without batching,
11594        // thousands of separate files could be created on boot.
11595        if (!isSystemApp || needsFlush) {
11596            new Thread("Error dump: " + dropboxTag) {
11597                @Override
11598                public void run() {
11599                    String report;
11600                    synchronized (sb) {
11601                        report = sb.toString();
11602                        sb.delete(0, sb.length());
11603                        sb.trimToSize();
11604                    }
11605                    if (report.length() != 0) {
11606                        dbox.addText(dropboxTag, report);
11607                    }
11608                }
11609            }.start();
11610            return;
11611        }
11612
11613        // System app batching:
11614        if (!bufferWasEmpty) {
11615            // An existing dropbox-writing thread is outstanding, so
11616            // we don't need to start it up.  The existing thread will
11617            // catch the buffer appends we just did.
11618            return;
11619        }
11620
11621        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11622        // (After this point, we shouldn't access AMS internal data structures.)
11623        new Thread("Error dump: " + dropboxTag) {
11624            @Override
11625            public void run() {
11626                // 5 second sleep to let stacks arrive and be batched together
11627                try {
11628                    Thread.sleep(5000);  // 5 seconds
11629                } catch (InterruptedException e) {}
11630
11631                String errorReport;
11632                synchronized (mStrictModeBuffer) {
11633                    errorReport = mStrictModeBuffer.toString();
11634                    if (errorReport.length() == 0) {
11635                        return;
11636                    }
11637                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11638                    mStrictModeBuffer.trimToSize();
11639                }
11640                dbox.addText(dropboxTag, errorReport);
11641            }
11642        }.start();
11643    }
11644
11645    /**
11646     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11647     * @param app object of the crashing app, null for the system server
11648     * @param tag reported by the caller
11649     * @param system whether this wtf is coming from the system
11650     * @param crashInfo describing the context of the error
11651     * @return true if the process should exit immediately (WTF is fatal)
11652     */
11653    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11654            final ApplicationErrorReport.CrashInfo crashInfo) {
11655        final ProcessRecord r = findAppProcess(app, "WTF");
11656        final String processName = app == null ? "system_server"
11657                : (r == null ? "unknown" : r.processName);
11658
11659        EventLog.writeEvent(EventLogTags.AM_WTF,
11660                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11661                processName,
11662                r == null ? -1 : r.info.flags,
11663                tag, crashInfo.exceptionMessage);
11664
11665        if (system) {
11666            // If this is coming from the system, we could very well have low-level
11667            // system locks held, so we want to do this all asynchronously.  And we
11668            // never want this to become fatal, so there is that too.
11669            mHandler.post(new Runnable() {
11670                @Override public void run() {
11671                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11672                            crashInfo);
11673                }
11674            });
11675            return false;
11676        }
11677
11678        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11679
11680        if (r != null && r.pid != Process.myPid() &&
11681                Settings.Global.getInt(mContext.getContentResolver(),
11682                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11683            crashApplication(r, crashInfo);
11684            return true;
11685        } else {
11686            return false;
11687        }
11688    }
11689
11690    /**
11691     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11692     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11693     */
11694    private ProcessRecord findAppProcess(IBinder app, String reason) {
11695        if (app == null) {
11696            return null;
11697        }
11698
11699        synchronized (this) {
11700            final int NP = mProcessNames.getMap().size();
11701            for (int ip=0; ip<NP; ip++) {
11702                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11703                final int NA = apps.size();
11704                for (int ia=0; ia<NA; ia++) {
11705                    ProcessRecord p = apps.valueAt(ia);
11706                    if (p.thread != null && p.thread.asBinder() == app) {
11707                        return p;
11708                    }
11709                }
11710            }
11711
11712            Slog.w(TAG, "Can't find mystery application for " + reason
11713                    + " from pid=" + Binder.getCallingPid()
11714                    + " uid=" + Binder.getCallingUid() + ": " + app);
11715            return null;
11716        }
11717    }
11718
11719    /**
11720     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11721     * to append various headers to the dropbox log text.
11722     */
11723    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11724            StringBuilder sb) {
11725        // Watchdog thread ends up invoking this function (with
11726        // a null ProcessRecord) to add the stack file to dropbox.
11727        // Do not acquire a lock on this (am) in such cases, as it
11728        // could cause a potential deadlock, if and when watchdog
11729        // is invoked due to unavailability of lock on am and it
11730        // would prevent watchdog from killing system_server.
11731        if (process == null) {
11732            sb.append("Process: ").append(processName).append("\n");
11733            return;
11734        }
11735        // Note: ProcessRecord 'process' is guarded by the service
11736        // instance.  (notably process.pkgList, which could otherwise change
11737        // concurrently during execution of this method)
11738        synchronized (this) {
11739            sb.append("Process: ").append(processName).append("\n");
11740            int flags = process.info.flags;
11741            IPackageManager pm = AppGlobals.getPackageManager();
11742            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11743            for (int ip=0; ip<process.pkgList.size(); ip++) {
11744                String pkg = process.pkgList.keyAt(ip);
11745                sb.append("Package: ").append(pkg);
11746                try {
11747                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11748                    if (pi != null) {
11749                        sb.append(" v").append(pi.versionCode);
11750                        if (pi.versionName != null) {
11751                            sb.append(" (").append(pi.versionName).append(")");
11752                        }
11753                    }
11754                } catch (RemoteException e) {
11755                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11756                }
11757                sb.append("\n");
11758            }
11759        }
11760    }
11761
11762    private static String processClass(ProcessRecord process) {
11763        if (process == null || process.pid == MY_PID) {
11764            return "system_server";
11765        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11766            return "system_app";
11767        } else {
11768            return "data_app";
11769        }
11770    }
11771
11772    /**
11773     * Write a description of an error (crash, WTF, ANR) to the drop box.
11774     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11775     * @param process which caused the error, null means the system server
11776     * @param activity which triggered the error, null if unknown
11777     * @param parent activity related to the error, null if unknown
11778     * @param subject line related to the error, null if absent
11779     * @param report in long form describing the error, null if absent
11780     * @param logFile to include in the report, null if none
11781     * @param crashInfo giving an application stack trace, null if absent
11782     */
11783    public void addErrorToDropBox(String eventType,
11784            ProcessRecord process, String processName, ActivityRecord activity,
11785            ActivityRecord parent, String subject,
11786            final String report, final File logFile,
11787            final ApplicationErrorReport.CrashInfo crashInfo) {
11788        // NOTE -- this must never acquire the ActivityManagerService lock,
11789        // otherwise the watchdog may be prevented from resetting the system.
11790
11791        final String dropboxTag = processClass(process) + "_" + eventType;
11792        final DropBoxManager dbox = (DropBoxManager)
11793                mContext.getSystemService(Context.DROPBOX_SERVICE);
11794
11795        // Exit early if the dropbox isn't configured to accept this report type.
11796        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11797
11798        final StringBuilder sb = new StringBuilder(1024);
11799        appendDropBoxProcessHeaders(process, processName, sb);
11800        if (activity != null) {
11801            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11802        }
11803        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11804            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11805        }
11806        if (parent != null && parent != activity) {
11807            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11808        }
11809        if (subject != null) {
11810            sb.append("Subject: ").append(subject).append("\n");
11811        }
11812        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11813        if (Debug.isDebuggerConnected()) {
11814            sb.append("Debugger: Connected\n");
11815        }
11816        sb.append("\n");
11817
11818        // Do the rest in a worker thread to avoid blocking the caller on I/O
11819        // (After this point, we shouldn't access AMS internal data structures.)
11820        Thread worker = new Thread("Error dump: " + dropboxTag) {
11821            @Override
11822            public void run() {
11823                if (report != null) {
11824                    sb.append(report);
11825                }
11826                if (logFile != null) {
11827                    try {
11828                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11829                                    "\n\n[[TRUNCATED]]"));
11830                    } catch (IOException e) {
11831                        Slog.e(TAG, "Error reading " + logFile, e);
11832                    }
11833                }
11834                if (crashInfo != null && crashInfo.stackTrace != null) {
11835                    sb.append(crashInfo.stackTrace);
11836                }
11837
11838                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11839                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11840                if (lines > 0) {
11841                    sb.append("\n");
11842
11843                    // Merge several logcat streams, and take the last N lines
11844                    InputStreamReader input = null;
11845                    try {
11846                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11847                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11848                                "-b", "crash",
11849                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11850
11851                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11852                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11853                        input = new InputStreamReader(logcat.getInputStream());
11854
11855                        int num;
11856                        char[] buf = new char[8192];
11857                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11858                    } catch (IOException e) {
11859                        Slog.e(TAG, "Error running logcat", e);
11860                    } finally {
11861                        if (input != null) try { input.close(); } catch (IOException e) {}
11862                    }
11863                }
11864
11865                dbox.addText(dropboxTag, sb.toString());
11866            }
11867        };
11868
11869        if (process == null) {
11870            // If process is null, we are being called from some internal code
11871            // and may be about to die -- run this synchronously.
11872            worker.run();
11873        } else {
11874            worker.start();
11875        }
11876    }
11877
11878    /**
11879     * Bring up the "unexpected error" dialog box for a crashing app.
11880     * Deal with edge cases (intercepts from instrumented applications,
11881     * ActivityController, error intent receivers, that sort of thing).
11882     * @param r the application crashing
11883     * @param crashInfo describing the failure
11884     */
11885    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11886        long timeMillis = System.currentTimeMillis();
11887        String shortMsg = crashInfo.exceptionClassName;
11888        String longMsg = crashInfo.exceptionMessage;
11889        String stackTrace = crashInfo.stackTrace;
11890        if (shortMsg != null && longMsg != null) {
11891            longMsg = shortMsg + ": " + longMsg;
11892        } else if (shortMsg != null) {
11893            longMsg = shortMsg;
11894        }
11895
11896        AppErrorResult result = new AppErrorResult();
11897        synchronized (this) {
11898            if (mController != null) {
11899                try {
11900                    String name = r != null ? r.processName : null;
11901                    int pid = r != null ? r.pid : Binder.getCallingPid();
11902                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11903                    if (!mController.appCrashed(name, pid,
11904                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11905                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11906                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11907                            Slog.w(TAG, "Skip killing native crashed app " + name
11908                                    + "(" + pid + ") during testing");
11909                        } else {
11910                            Slog.w(TAG, "Force-killing crashed app " + name
11911                                    + " at watcher's request");
11912                            if (r != null) {
11913                                r.kill("crash", true);
11914                            } else {
11915                                // Huh.
11916                                Process.killProcess(pid);
11917                                Process.killProcessGroup(uid, pid);
11918                            }
11919                        }
11920                        return;
11921                    }
11922                } catch (RemoteException e) {
11923                    mController = null;
11924                    Watchdog.getInstance().setActivityController(null);
11925                }
11926            }
11927
11928            final long origId = Binder.clearCallingIdentity();
11929
11930            // If this process is running instrumentation, finish it.
11931            if (r != null && r.instrumentationClass != null) {
11932                Slog.w(TAG, "Error in app " + r.processName
11933                      + " running instrumentation " + r.instrumentationClass + ":");
11934                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11935                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11936                Bundle info = new Bundle();
11937                info.putString("shortMsg", shortMsg);
11938                info.putString("longMsg", longMsg);
11939                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11940                Binder.restoreCallingIdentity(origId);
11941                return;
11942            }
11943
11944            // If we can't identify the process or it's already exceeded its crash quota,
11945            // quit right away without showing a crash dialog.
11946            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11947                Binder.restoreCallingIdentity(origId);
11948                return;
11949            }
11950
11951            Message msg = Message.obtain();
11952            msg.what = SHOW_ERROR_MSG;
11953            HashMap data = new HashMap();
11954            data.put("result", result);
11955            data.put("app", r);
11956            msg.obj = data;
11957            mHandler.sendMessage(msg);
11958
11959            Binder.restoreCallingIdentity(origId);
11960        }
11961
11962        int res = result.get();
11963
11964        Intent appErrorIntent = null;
11965        synchronized (this) {
11966            if (r != null && !r.isolated) {
11967                // XXX Can't keep track of crash time for isolated processes,
11968                // since they don't have a persistent identity.
11969                mProcessCrashTimes.put(r.info.processName, r.uid,
11970                        SystemClock.uptimeMillis());
11971            }
11972            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11973                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11974            }
11975        }
11976
11977        if (appErrorIntent != null) {
11978            try {
11979                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11980            } catch (ActivityNotFoundException e) {
11981                Slog.w(TAG, "bug report receiver dissappeared", e);
11982            }
11983        }
11984    }
11985
11986    Intent createAppErrorIntentLocked(ProcessRecord r,
11987            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11988        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11989        if (report == null) {
11990            return null;
11991        }
11992        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11993        result.setComponent(r.errorReportReceiver);
11994        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11995        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11996        return result;
11997    }
11998
11999    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12000            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12001        if (r.errorReportReceiver == null) {
12002            return null;
12003        }
12004
12005        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12006            return null;
12007        }
12008
12009        ApplicationErrorReport report = new ApplicationErrorReport();
12010        report.packageName = r.info.packageName;
12011        report.installerPackageName = r.errorReportReceiver.getPackageName();
12012        report.processName = r.processName;
12013        report.time = timeMillis;
12014        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12015
12016        if (r.crashing || r.forceCrashReport) {
12017            report.type = ApplicationErrorReport.TYPE_CRASH;
12018            report.crashInfo = crashInfo;
12019        } else if (r.notResponding) {
12020            report.type = ApplicationErrorReport.TYPE_ANR;
12021            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12022
12023            report.anrInfo.activity = r.notRespondingReport.tag;
12024            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12025            report.anrInfo.info = r.notRespondingReport.longMsg;
12026        }
12027
12028        return report;
12029    }
12030
12031    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12032        enforceNotIsolatedCaller("getProcessesInErrorState");
12033        // assume our apps are happy - lazy create the list
12034        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12035
12036        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12037                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12038        int userId = UserHandle.getUserId(Binder.getCallingUid());
12039
12040        synchronized (this) {
12041
12042            // iterate across all processes
12043            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12044                ProcessRecord app = mLruProcesses.get(i);
12045                if (!allUsers && app.userId != userId) {
12046                    continue;
12047                }
12048                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12049                    // This one's in trouble, so we'll generate a report for it
12050                    // crashes are higher priority (in case there's a crash *and* an anr)
12051                    ActivityManager.ProcessErrorStateInfo report = null;
12052                    if (app.crashing) {
12053                        report = app.crashingReport;
12054                    } else if (app.notResponding) {
12055                        report = app.notRespondingReport;
12056                    }
12057
12058                    if (report != null) {
12059                        if (errList == null) {
12060                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12061                        }
12062                        errList.add(report);
12063                    } else {
12064                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12065                                " crashing = " + app.crashing +
12066                                " notResponding = " + app.notResponding);
12067                    }
12068                }
12069            }
12070        }
12071
12072        return errList;
12073    }
12074
12075    static int procStateToImportance(int procState, int memAdj,
12076            ActivityManager.RunningAppProcessInfo currApp) {
12077        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12078        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12079            currApp.lru = memAdj;
12080        } else {
12081            currApp.lru = 0;
12082        }
12083        return imp;
12084    }
12085
12086    private void fillInProcMemInfo(ProcessRecord app,
12087            ActivityManager.RunningAppProcessInfo outInfo) {
12088        outInfo.pid = app.pid;
12089        outInfo.uid = app.info.uid;
12090        if (mHeavyWeightProcess == app) {
12091            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12092        }
12093        if (app.persistent) {
12094            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12095        }
12096        if (app.activities.size() > 0) {
12097            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12098        }
12099        outInfo.lastTrimLevel = app.trimMemoryLevel;
12100        int adj = app.curAdj;
12101        int procState = app.curProcState;
12102        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12103        outInfo.importanceReasonCode = app.adjTypeCode;
12104        outInfo.processState = app.curProcState;
12105    }
12106
12107    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12108        enforceNotIsolatedCaller("getRunningAppProcesses");
12109        // Lazy instantiation of list
12110        List<ActivityManager.RunningAppProcessInfo> runList = null;
12111        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12112                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12113        int userId = UserHandle.getUserId(Binder.getCallingUid());
12114        synchronized (this) {
12115            // Iterate across all processes
12116            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12117                ProcessRecord app = mLruProcesses.get(i);
12118                if (!allUsers && app.userId != userId) {
12119                    continue;
12120                }
12121                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12122                    // Generate process state info for running application
12123                    ActivityManager.RunningAppProcessInfo currApp =
12124                        new ActivityManager.RunningAppProcessInfo(app.processName,
12125                                app.pid, app.getPackageList());
12126                    fillInProcMemInfo(app, currApp);
12127                    if (app.adjSource instanceof ProcessRecord) {
12128                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12129                        currApp.importanceReasonImportance =
12130                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12131                                        app.adjSourceProcState);
12132                    } else if (app.adjSource instanceof ActivityRecord) {
12133                        ActivityRecord r = (ActivityRecord)app.adjSource;
12134                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12135                    }
12136                    if (app.adjTarget instanceof ComponentName) {
12137                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12138                    }
12139                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12140                    //        + " lru=" + currApp.lru);
12141                    if (runList == null) {
12142                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12143                    }
12144                    runList.add(currApp);
12145                }
12146            }
12147        }
12148        return runList;
12149    }
12150
12151    public List<ApplicationInfo> getRunningExternalApplications() {
12152        enforceNotIsolatedCaller("getRunningExternalApplications");
12153        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12154        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12155        if (runningApps != null && runningApps.size() > 0) {
12156            Set<String> extList = new HashSet<String>();
12157            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12158                if (app.pkgList != null) {
12159                    for (String pkg : app.pkgList) {
12160                        extList.add(pkg);
12161                    }
12162                }
12163            }
12164            IPackageManager pm = AppGlobals.getPackageManager();
12165            for (String pkg : extList) {
12166                try {
12167                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12168                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12169                        retList.add(info);
12170                    }
12171                } catch (RemoteException e) {
12172                }
12173            }
12174        }
12175        return retList;
12176    }
12177
12178    @Override
12179    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12180        enforceNotIsolatedCaller("getMyMemoryState");
12181        synchronized (this) {
12182            ProcessRecord proc;
12183            synchronized (mPidsSelfLocked) {
12184                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12185            }
12186            fillInProcMemInfo(proc, outInfo);
12187        }
12188    }
12189
12190    @Override
12191    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12192        if (checkCallingPermission(android.Manifest.permission.DUMP)
12193                != PackageManager.PERMISSION_GRANTED) {
12194            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12195                    + Binder.getCallingPid()
12196                    + ", uid=" + Binder.getCallingUid()
12197                    + " without permission "
12198                    + android.Manifest.permission.DUMP);
12199            return;
12200        }
12201
12202        boolean dumpAll = false;
12203        boolean dumpClient = false;
12204        String dumpPackage = null;
12205
12206        int opti = 0;
12207        while (opti < args.length) {
12208            String opt = args[opti];
12209            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12210                break;
12211            }
12212            opti++;
12213            if ("-a".equals(opt)) {
12214                dumpAll = true;
12215            } else if ("-c".equals(opt)) {
12216                dumpClient = true;
12217            } else if ("-h".equals(opt)) {
12218                pw.println("Activity manager dump options:");
12219                pw.println("  [-a] [-c] [-h] [cmd] ...");
12220                pw.println("  cmd may be one of:");
12221                pw.println("    a[ctivities]: activity stack state");
12222                pw.println("    r[recents]: recent activities state");
12223                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12224                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12225                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12226                pw.println("    o[om]: out of memory management");
12227                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12228                pw.println("    provider [COMP_SPEC]: provider client-side state");
12229                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12230                pw.println("    service [COMP_SPEC]: service client-side state");
12231                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12232                pw.println("    all: dump all activities");
12233                pw.println("    top: dump the top activity");
12234                pw.println("    write: write all pending state to storage");
12235                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12236                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12237                pw.println("    a partial substring in a component name, a");
12238                pw.println("    hex object identifier.");
12239                pw.println("  -a: include all available server state.");
12240                pw.println("  -c: include client state.");
12241                return;
12242            } else {
12243                pw.println("Unknown argument: " + opt + "; use -h for help");
12244            }
12245        }
12246
12247        long origId = Binder.clearCallingIdentity();
12248        boolean more = false;
12249        // Is the caller requesting to dump a particular piece of data?
12250        if (opti < args.length) {
12251            String cmd = args[opti];
12252            opti++;
12253            if ("activities".equals(cmd) || "a".equals(cmd)) {
12254                synchronized (this) {
12255                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12256                }
12257            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12258                synchronized (this) {
12259                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12260                }
12261            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12262                String[] newArgs;
12263                String name;
12264                if (opti >= args.length) {
12265                    name = null;
12266                    newArgs = EMPTY_STRING_ARRAY;
12267                } else {
12268                    name = args[opti];
12269                    opti++;
12270                    newArgs = new String[args.length - opti];
12271                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12272                            args.length - opti);
12273                }
12274                synchronized (this) {
12275                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12276                }
12277            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12278                String[] newArgs;
12279                String name;
12280                if (opti >= args.length) {
12281                    name = null;
12282                    newArgs = EMPTY_STRING_ARRAY;
12283                } else {
12284                    name = args[opti];
12285                    opti++;
12286                    newArgs = new String[args.length - opti];
12287                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12288                            args.length - opti);
12289                }
12290                synchronized (this) {
12291                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12292                }
12293            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12294                String[] newArgs;
12295                String name;
12296                if (opti >= args.length) {
12297                    name = null;
12298                    newArgs = EMPTY_STRING_ARRAY;
12299                } else {
12300                    name = args[opti];
12301                    opti++;
12302                    newArgs = new String[args.length - opti];
12303                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12304                            args.length - opti);
12305                }
12306                synchronized (this) {
12307                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12308                }
12309            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12310                synchronized (this) {
12311                    dumpOomLocked(fd, pw, args, opti, true);
12312                }
12313            } else if ("provider".equals(cmd)) {
12314                String[] newArgs;
12315                String name;
12316                if (opti >= args.length) {
12317                    name = null;
12318                    newArgs = EMPTY_STRING_ARRAY;
12319                } else {
12320                    name = args[opti];
12321                    opti++;
12322                    newArgs = new String[args.length - opti];
12323                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12324                }
12325                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12326                    pw.println("No providers match: " + name);
12327                    pw.println("Use -h for help.");
12328                }
12329            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12330                synchronized (this) {
12331                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12332                }
12333            } else if ("service".equals(cmd)) {
12334                String[] newArgs;
12335                String name;
12336                if (opti >= args.length) {
12337                    name = null;
12338                    newArgs = EMPTY_STRING_ARRAY;
12339                } else {
12340                    name = args[opti];
12341                    opti++;
12342                    newArgs = new String[args.length - opti];
12343                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12344                            args.length - opti);
12345                }
12346                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12347                    pw.println("No services match: " + name);
12348                    pw.println("Use -h for help.");
12349                }
12350            } else if ("package".equals(cmd)) {
12351                String[] newArgs;
12352                if (opti >= args.length) {
12353                    pw.println("package: no package name specified");
12354                    pw.println("Use -h for help.");
12355                } else {
12356                    dumpPackage = args[opti];
12357                    opti++;
12358                    newArgs = new String[args.length - opti];
12359                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12360                            args.length - opti);
12361                    args = newArgs;
12362                    opti = 0;
12363                    more = true;
12364                }
12365            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12366                synchronized (this) {
12367                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12368                }
12369            } else if ("write".equals(cmd)) {
12370                mTaskPersister.flush();
12371                pw.println("All tasks persisted.");
12372                return;
12373            } else {
12374                // Dumping a single activity?
12375                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12376                    pw.println("Bad activity command, or no activities match: " + cmd);
12377                    pw.println("Use -h for help.");
12378                }
12379            }
12380            if (!more) {
12381                Binder.restoreCallingIdentity(origId);
12382                return;
12383            }
12384        }
12385
12386        // No piece of data specified, dump everything.
12387        synchronized (this) {
12388            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12389            pw.println();
12390            if (dumpAll) {
12391                pw.println("-------------------------------------------------------------------------------");
12392            }
12393            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12394            pw.println();
12395            if (dumpAll) {
12396                pw.println("-------------------------------------------------------------------------------");
12397            }
12398            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12399            pw.println();
12400            if (dumpAll) {
12401                pw.println("-------------------------------------------------------------------------------");
12402            }
12403            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12404            pw.println();
12405            if (dumpAll) {
12406                pw.println("-------------------------------------------------------------------------------");
12407            }
12408            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12409            pw.println();
12410            if (dumpAll) {
12411                pw.println("-------------------------------------------------------------------------------");
12412            }
12413            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12414            pw.println();
12415            if (dumpAll) {
12416                pw.println("-------------------------------------------------------------------------------");
12417            }
12418            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12419        }
12420        Binder.restoreCallingIdentity(origId);
12421    }
12422
12423    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12424            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12425        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12426
12427        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12428                dumpPackage);
12429        boolean needSep = printedAnything;
12430
12431        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12432                dumpPackage, needSep, "  mFocusedActivity: ");
12433        if (printed) {
12434            printedAnything = true;
12435            needSep = false;
12436        }
12437
12438        if (dumpPackage == null) {
12439            if (needSep) {
12440                pw.println();
12441            }
12442            needSep = true;
12443            printedAnything = true;
12444            mStackSupervisor.dump(pw, "  ");
12445        }
12446
12447        if (!printedAnything) {
12448            pw.println("  (nothing)");
12449        }
12450    }
12451
12452    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12453            int opti, boolean dumpAll, String dumpPackage) {
12454        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12455
12456        boolean printedAnything = false;
12457
12458        if (mRecentTasks.size() > 0) {
12459            boolean printedHeader = false;
12460
12461            final int N = mRecentTasks.size();
12462            for (int i=0; i<N; i++) {
12463                TaskRecord tr = mRecentTasks.get(i);
12464                if (dumpPackage != null) {
12465                    if (tr.realActivity == null ||
12466                            !dumpPackage.equals(tr.realActivity)) {
12467                        continue;
12468                    }
12469                }
12470                if (!printedHeader) {
12471                    pw.println("  Recent tasks:");
12472                    printedHeader = true;
12473                    printedAnything = true;
12474                }
12475                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12476                        pw.println(tr);
12477                if (dumpAll) {
12478                    mRecentTasks.get(i).dump(pw, "    ");
12479                }
12480            }
12481        }
12482
12483        if (!printedAnything) {
12484            pw.println("  (nothing)");
12485        }
12486    }
12487
12488    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12489            int opti, boolean dumpAll, String dumpPackage) {
12490        boolean needSep = false;
12491        boolean printedAnything = false;
12492        int numPers = 0;
12493
12494        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12495
12496        if (dumpAll) {
12497            final int NP = mProcessNames.getMap().size();
12498            for (int ip=0; ip<NP; ip++) {
12499                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12500                final int NA = procs.size();
12501                for (int ia=0; ia<NA; ia++) {
12502                    ProcessRecord r = procs.valueAt(ia);
12503                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12504                        continue;
12505                    }
12506                    if (!needSep) {
12507                        pw.println("  All known processes:");
12508                        needSep = true;
12509                        printedAnything = true;
12510                    }
12511                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12512                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12513                        pw.print(" "); pw.println(r);
12514                    r.dump(pw, "    ");
12515                    if (r.persistent) {
12516                        numPers++;
12517                    }
12518                }
12519            }
12520        }
12521
12522        if (mIsolatedProcesses.size() > 0) {
12523            boolean printed = false;
12524            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12525                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12526                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12527                    continue;
12528                }
12529                if (!printed) {
12530                    if (needSep) {
12531                        pw.println();
12532                    }
12533                    pw.println("  Isolated process list (sorted by uid):");
12534                    printedAnything = true;
12535                    printed = true;
12536                    needSep = true;
12537                }
12538                pw.println(String.format("%sIsolated #%2d: %s",
12539                        "    ", i, r.toString()));
12540            }
12541        }
12542
12543        if (mLruProcesses.size() > 0) {
12544            if (needSep) {
12545                pw.println();
12546            }
12547            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12548                    pw.print(" total, non-act at ");
12549                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12550                    pw.print(", non-svc at ");
12551                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12552                    pw.println("):");
12553            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12554            needSep = true;
12555            printedAnything = true;
12556        }
12557
12558        if (dumpAll || dumpPackage != null) {
12559            synchronized (mPidsSelfLocked) {
12560                boolean printed = false;
12561                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12562                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12563                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12564                        continue;
12565                    }
12566                    if (!printed) {
12567                        if (needSep) pw.println();
12568                        needSep = true;
12569                        pw.println("  PID mappings:");
12570                        printed = true;
12571                        printedAnything = true;
12572                    }
12573                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12574                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12575                }
12576            }
12577        }
12578
12579        if (mForegroundProcesses.size() > 0) {
12580            synchronized (mPidsSelfLocked) {
12581                boolean printed = false;
12582                for (int i=0; i<mForegroundProcesses.size(); i++) {
12583                    ProcessRecord r = mPidsSelfLocked.get(
12584                            mForegroundProcesses.valueAt(i).pid);
12585                    if (dumpPackage != null && (r == null
12586                            || !r.pkgList.containsKey(dumpPackage))) {
12587                        continue;
12588                    }
12589                    if (!printed) {
12590                        if (needSep) pw.println();
12591                        needSep = true;
12592                        pw.println("  Foreground Processes:");
12593                        printed = true;
12594                        printedAnything = true;
12595                    }
12596                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12597                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12598                }
12599            }
12600        }
12601
12602        if (mPersistentStartingProcesses.size() > 0) {
12603            if (needSep) pw.println();
12604            needSep = true;
12605            printedAnything = true;
12606            pw.println("  Persisent processes that are starting:");
12607            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12608                    "Starting Norm", "Restarting PERS", dumpPackage);
12609        }
12610
12611        if (mRemovedProcesses.size() > 0) {
12612            if (needSep) pw.println();
12613            needSep = true;
12614            printedAnything = true;
12615            pw.println("  Processes that are being removed:");
12616            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12617                    "Removed Norm", "Removed PERS", dumpPackage);
12618        }
12619
12620        if (mProcessesOnHold.size() > 0) {
12621            if (needSep) pw.println();
12622            needSep = true;
12623            printedAnything = true;
12624            pw.println("  Processes that are on old until the system is ready:");
12625            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12626                    "OnHold Norm", "OnHold PERS", dumpPackage);
12627        }
12628
12629        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12630
12631        if (mProcessCrashTimes.getMap().size() > 0) {
12632            boolean printed = false;
12633            long now = SystemClock.uptimeMillis();
12634            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12635            final int NP = pmap.size();
12636            for (int ip=0; ip<NP; ip++) {
12637                String pname = pmap.keyAt(ip);
12638                SparseArray<Long> uids = pmap.valueAt(ip);
12639                final int N = uids.size();
12640                for (int i=0; i<N; i++) {
12641                    int puid = uids.keyAt(i);
12642                    ProcessRecord r = mProcessNames.get(pname, puid);
12643                    if (dumpPackage != null && (r == null
12644                            || !r.pkgList.containsKey(dumpPackage))) {
12645                        continue;
12646                    }
12647                    if (!printed) {
12648                        if (needSep) pw.println();
12649                        needSep = true;
12650                        pw.println("  Time since processes crashed:");
12651                        printed = true;
12652                        printedAnything = true;
12653                    }
12654                    pw.print("    Process "); pw.print(pname);
12655                            pw.print(" uid "); pw.print(puid);
12656                            pw.print(": last crashed ");
12657                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12658                            pw.println(" ago");
12659                }
12660            }
12661        }
12662
12663        if (mBadProcesses.getMap().size() > 0) {
12664            boolean printed = false;
12665            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12666            final int NP = pmap.size();
12667            for (int ip=0; ip<NP; ip++) {
12668                String pname = pmap.keyAt(ip);
12669                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12670                final int N = uids.size();
12671                for (int i=0; i<N; i++) {
12672                    int puid = uids.keyAt(i);
12673                    ProcessRecord r = mProcessNames.get(pname, puid);
12674                    if (dumpPackage != null && (r == null
12675                            || !r.pkgList.containsKey(dumpPackage))) {
12676                        continue;
12677                    }
12678                    if (!printed) {
12679                        if (needSep) pw.println();
12680                        needSep = true;
12681                        pw.println("  Bad processes:");
12682                        printedAnything = true;
12683                    }
12684                    BadProcessInfo info = uids.valueAt(i);
12685                    pw.print("    Bad process "); pw.print(pname);
12686                            pw.print(" uid "); pw.print(puid);
12687                            pw.print(": crashed at time "); pw.println(info.time);
12688                    if (info.shortMsg != null) {
12689                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12690                    }
12691                    if (info.longMsg != null) {
12692                        pw.print("      Long msg: "); pw.println(info.longMsg);
12693                    }
12694                    if (info.stack != null) {
12695                        pw.println("      Stack:");
12696                        int lastPos = 0;
12697                        for (int pos=0; pos<info.stack.length(); pos++) {
12698                            if (info.stack.charAt(pos) == '\n') {
12699                                pw.print("        ");
12700                                pw.write(info.stack, lastPos, pos-lastPos);
12701                                pw.println();
12702                                lastPos = pos+1;
12703                            }
12704                        }
12705                        if (lastPos < info.stack.length()) {
12706                            pw.print("        ");
12707                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12708                            pw.println();
12709                        }
12710                    }
12711                }
12712            }
12713        }
12714
12715        if (dumpPackage == null) {
12716            pw.println();
12717            needSep = false;
12718            pw.println("  mStartedUsers:");
12719            for (int i=0; i<mStartedUsers.size(); i++) {
12720                UserStartedState uss = mStartedUsers.valueAt(i);
12721                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12722                        pw.print(": "); uss.dump("", pw);
12723            }
12724            pw.print("  mStartedUserArray: [");
12725            for (int i=0; i<mStartedUserArray.length; i++) {
12726                if (i > 0) pw.print(", ");
12727                pw.print(mStartedUserArray[i]);
12728            }
12729            pw.println("]");
12730            pw.print("  mUserLru: [");
12731            for (int i=0; i<mUserLru.size(); i++) {
12732                if (i > 0) pw.print(", ");
12733                pw.print(mUserLru.get(i));
12734            }
12735            pw.println("]");
12736            if (dumpAll) {
12737                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12738            }
12739            synchronized (mUserProfileGroupIdsSelfLocked) {
12740                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12741                    pw.println("  mUserProfileGroupIds:");
12742                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12743                        pw.print("    User #");
12744                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12745                        pw.print(" -> profile #");
12746                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12747                    }
12748                }
12749            }
12750        }
12751        if (mHomeProcess != null && (dumpPackage == null
12752                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12753            if (needSep) {
12754                pw.println();
12755                needSep = false;
12756            }
12757            pw.println("  mHomeProcess: " + mHomeProcess);
12758        }
12759        if (mPreviousProcess != null && (dumpPackage == null
12760                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12761            if (needSep) {
12762                pw.println();
12763                needSep = false;
12764            }
12765            pw.println("  mPreviousProcess: " + mPreviousProcess);
12766        }
12767        if (dumpAll) {
12768            StringBuilder sb = new StringBuilder(128);
12769            sb.append("  mPreviousProcessVisibleTime: ");
12770            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12771            pw.println(sb);
12772        }
12773        if (mHeavyWeightProcess != null && (dumpPackage == null
12774                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12775            if (needSep) {
12776                pw.println();
12777                needSep = false;
12778            }
12779            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12780        }
12781        if (dumpPackage == null) {
12782            pw.println("  mConfiguration: " + mConfiguration);
12783        }
12784        if (dumpAll) {
12785            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12786            if (mCompatModePackages.getPackages().size() > 0) {
12787                boolean printed = false;
12788                for (Map.Entry<String, Integer> entry
12789                        : mCompatModePackages.getPackages().entrySet()) {
12790                    String pkg = entry.getKey();
12791                    int mode = entry.getValue();
12792                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12793                        continue;
12794                    }
12795                    if (!printed) {
12796                        pw.println("  mScreenCompatPackages:");
12797                        printed = true;
12798                    }
12799                    pw.print("    "); pw.print(pkg); pw.print(": ");
12800                            pw.print(mode); pw.println();
12801                }
12802            }
12803        }
12804        if (dumpPackage == null) {
12805            if (mSleeping || mWentToSleep || mLockScreenShown) {
12806                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12807                        + " mLockScreenShown " + mLockScreenShown);
12808            }
12809            if (mShuttingDown || mRunningVoice) {
12810                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12811            }
12812        }
12813        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12814                || mOrigWaitForDebugger) {
12815            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12816                    || dumpPackage.equals(mOrigDebugApp)) {
12817                if (needSep) {
12818                    pw.println();
12819                    needSep = false;
12820                }
12821                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12822                        + " mDebugTransient=" + mDebugTransient
12823                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12824            }
12825        }
12826        if (mOpenGlTraceApp != null) {
12827            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12828                if (needSep) {
12829                    pw.println();
12830                    needSep = false;
12831                }
12832                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12833            }
12834        }
12835        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12836                || mProfileFd != null) {
12837            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12838                if (needSep) {
12839                    pw.println();
12840                    needSep = false;
12841                }
12842                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12843                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12844                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12845                        + mAutoStopProfiler);
12846                pw.println("  mProfileType=" + mProfileType);
12847            }
12848        }
12849        if (dumpPackage == null) {
12850            if (mAlwaysFinishActivities || mController != null) {
12851                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12852                        + " mController=" + mController);
12853            }
12854            if (dumpAll) {
12855                pw.println("  Total persistent processes: " + numPers);
12856                pw.println("  mProcessesReady=" + mProcessesReady
12857                        + " mSystemReady=" + mSystemReady);
12858                pw.println("  mBooting=" + mBooting
12859                        + " mBooted=" + mBooted
12860                        + " mFactoryTest=" + mFactoryTest);
12861                pw.print("  mLastPowerCheckRealtime=");
12862                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12863                        pw.println("");
12864                pw.print("  mLastPowerCheckUptime=");
12865                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12866                        pw.println("");
12867                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12868                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12869                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12870                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12871                        + " (" + mLruProcesses.size() + " total)"
12872                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12873                        + " mNumServiceProcs=" + mNumServiceProcs
12874                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12875                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12876                        + " mLastMemoryLevel" + mLastMemoryLevel
12877                        + " mLastNumProcesses" + mLastNumProcesses);
12878                long now = SystemClock.uptimeMillis();
12879                pw.print("  mLastIdleTime=");
12880                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12881                        pw.print(" mLowRamSinceLastIdle=");
12882                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12883                        pw.println();
12884            }
12885        }
12886
12887        if (!printedAnything) {
12888            pw.println("  (nothing)");
12889        }
12890    }
12891
12892    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12893            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12894        if (mProcessesToGc.size() > 0) {
12895            boolean printed = false;
12896            long now = SystemClock.uptimeMillis();
12897            for (int i=0; i<mProcessesToGc.size(); i++) {
12898                ProcessRecord proc = mProcessesToGc.get(i);
12899                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12900                    continue;
12901                }
12902                if (!printed) {
12903                    if (needSep) pw.println();
12904                    needSep = true;
12905                    pw.println("  Processes that are waiting to GC:");
12906                    printed = true;
12907                }
12908                pw.print("    Process "); pw.println(proc);
12909                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12910                        pw.print(", last gced=");
12911                        pw.print(now-proc.lastRequestedGc);
12912                        pw.print(" ms ago, last lowMem=");
12913                        pw.print(now-proc.lastLowMemory);
12914                        pw.println(" ms ago");
12915
12916            }
12917        }
12918        return needSep;
12919    }
12920
12921    void printOomLevel(PrintWriter pw, String name, int adj) {
12922        pw.print("    ");
12923        if (adj >= 0) {
12924            pw.print(' ');
12925            if (adj < 10) pw.print(' ');
12926        } else {
12927            if (adj > -10) pw.print(' ');
12928        }
12929        pw.print(adj);
12930        pw.print(": ");
12931        pw.print(name);
12932        pw.print(" (");
12933        pw.print(mProcessList.getMemLevel(adj)/1024);
12934        pw.println(" kB)");
12935    }
12936
12937    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12938            int opti, boolean dumpAll) {
12939        boolean needSep = false;
12940
12941        if (mLruProcesses.size() > 0) {
12942            if (needSep) pw.println();
12943            needSep = true;
12944            pw.println("  OOM levels:");
12945            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12946            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12947            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12948            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12949            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12950            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12951            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12952            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12953            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12954            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12955            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12956            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12957            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12958
12959            if (needSep) pw.println();
12960            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12961                    pw.print(" total, non-act at ");
12962                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12963                    pw.print(", non-svc at ");
12964                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12965                    pw.println("):");
12966            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12967            needSep = true;
12968        }
12969
12970        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12971
12972        pw.println();
12973        pw.println("  mHomeProcess: " + mHomeProcess);
12974        pw.println("  mPreviousProcess: " + mPreviousProcess);
12975        if (mHeavyWeightProcess != null) {
12976            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12977        }
12978
12979        return true;
12980    }
12981
12982    /**
12983     * There are three ways to call this:
12984     *  - no provider specified: dump all the providers
12985     *  - a flattened component name that matched an existing provider was specified as the
12986     *    first arg: dump that one provider
12987     *  - the first arg isn't the flattened component name of an existing provider:
12988     *    dump all providers whose component contains the first arg as a substring
12989     */
12990    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12991            int opti, boolean dumpAll) {
12992        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12993    }
12994
12995    static class ItemMatcher {
12996        ArrayList<ComponentName> components;
12997        ArrayList<String> strings;
12998        ArrayList<Integer> objects;
12999        boolean all;
13000
13001        ItemMatcher() {
13002            all = true;
13003        }
13004
13005        void build(String name) {
13006            ComponentName componentName = ComponentName.unflattenFromString(name);
13007            if (componentName != null) {
13008                if (components == null) {
13009                    components = new ArrayList<ComponentName>();
13010                }
13011                components.add(componentName);
13012                all = false;
13013            } else {
13014                int objectId = 0;
13015                // Not a '/' separated full component name; maybe an object ID?
13016                try {
13017                    objectId = Integer.parseInt(name, 16);
13018                    if (objects == null) {
13019                        objects = new ArrayList<Integer>();
13020                    }
13021                    objects.add(objectId);
13022                    all = false;
13023                } catch (RuntimeException e) {
13024                    // Not an integer; just do string match.
13025                    if (strings == null) {
13026                        strings = new ArrayList<String>();
13027                    }
13028                    strings.add(name);
13029                    all = false;
13030                }
13031            }
13032        }
13033
13034        int build(String[] args, int opti) {
13035            for (; opti<args.length; opti++) {
13036                String name = args[opti];
13037                if ("--".equals(name)) {
13038                    return opti+1;
13039                }
13040                build(name);
13041            }
13042            return opti;
13043        }
13044
13045        boolean match(Object object, ComponentName comp) {
13046            if (all) {
13047                return true;
13048            }
13049            if (components != null) {
13050                for (int i=0; i<components.size(); i++) {
13051                    if (components.get(i).equals(comp)) {
13052                        return true;
13053                    }
13054                }
13055            }
13056            if (objects != null) {
13057                for (int i=0; i<objects.size(); i++) {
13058                    if (System.identityHashCode(object) == objects.get(i)) {
13059                        return true;
13060                    }
13061                }
13062            }
13063            if (strings != null) {
13064                String flat = comp.flattenToString();
13065                for (int i=0; i<strings.size(); i++) {
13066                    if (flat.contains(strings.get(i))) {
13067                        return true;
13068                    }
13069                }
13070            }
13071            return false;
13072        }
13073    }
13074
13075    /**
13076     * There are three things that cmd can be:
13077     *  - a flattened component name that matches an existing activity
13078     *  - the cmd arg isn't the flattened component name of an existing activity:
13079     *    dump all activity whose component contains the cmd as a substring
13080     *  - A hex number of the ActivityRecord object instance.
13081     */
13082    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13083            int opti, boolean dumpAll) {
13084        ArrayList<ActivityRecord> activities;
13085
13086        synchronized (this) {
13087            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13088        }
13089
13090        if (activities.size() <= 0) {
13091            return false;
13092        }
13093
13094        String[] newArgs = new String[args.length - opti];
13095        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13096
13097        TaskRecord lastTask = null;
13098        boolean needSep = false;
13099        for (int i=activities.size()-1; i>=0; i--) {
13100            ActivityRecord r = activities.get(i);
13101            if (needSep) {
13102                pw.println();
13103            }
13104            needSep = true;
13105            synchronized (this) {
13106                if (lastTask != r.task) {
13107                    lastTask = r.task;
13108                    pw.print("TASK "); pw.print(lastTask.affinity);
13109                            pw.print(" id="); pw.println(lastTask.taskId);
13110                    if (dumpAll) {
13111                        lastTask.dump(pw, "  ");
13112                    }
13113                }
13114            }
13115            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13116        }
13117        return true;
13118    }
13119
13120    /**
13121     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13122     * there is a thread associated with the activity.
13123     */
13124    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13125            final ActivityRecord r, String[] args, boolean dumpAll) {
13126        String innerPrefix = prefix + "  ";
13127        synchronized (this) {
13128            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13129                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13130                    pw.print(" pid=");
13131                    if (r.app != null) pw.println(r.app.pid);
13132                    else pw.println("(not running)");
13133            if (dumpAll) {
13134                r.dump(pw, innerPrefix);
13135            }
13136        }
13137        if (r.app != null && r.app.thread != null) {
13138            // flush anything that is already in the PrintWriter since the thread is going
13139            // to write to the file descriptor directly
13140            pw.flush();
13141            try {
13142                TransferPipe tp = new TransferPipe();
13143                try {
13144                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13145                            r.appToken, innerPrefix, args);
13146                    tp.go(fd);
13147                } finally {
13148                    tp.kill();
13149                }
13150            } catch (IOException e) {
13151                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13152            } catch (RemoteException e) {
13153                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13154            }
13155        }
13156    }
13157
13158    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13159            int opti, boolean dumpAll, String dumpPackage) {
13160        boolean needSep = false;
13161        boolean onlyHistory = false;
13162        boolean printedAnything = false;
13163
13164        if ("history".equals(dumpPackage)) {
13165            if (opti < args.length && "-s".equals(args[opti])) {
13166                dumpAll = false;
13167            }
13168            onlyHistory = true;
13169            dumpPackage = null;
13170        }
13171
13172        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13173        if (!onlyHistory && dumpAll) {
13174            if (mRegisteredReceivers.size() > 0) {
13175                boolean printed = false;
13176                Iterator it = mRegisteredReceivers.values().iterator();
13177                while (it.hasNext()) {
13178                    ReceiverList r = (ReceiverList)it.next();
13179                    if (dumpPackage != null && (r.app == null ||
13180                            !dumpPackage.equals(r.app.info.packageName))) {
13181                        continue;
13182                    }
13183                    if (!printed) {
13184                        pw.println("  Registered Receivers:");
13185                        needSep = true;
13186                        printed = true;
13187                        printedAnything = true;
13188                    }
13189                    pw.print("  * "); pw.println(r);
13190                    r.dump(pw, "    ");
13191                }
13192            }
13193
13194            if (mReceiverResolver.dump(pw, needSep ?
13195                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13196                    "    ", dumpPackage, false)) {
13197                needSep = true;
13198                printedAnything = true;
13199            }
13200        }
13201
13202        for (BroadcastQueue q : mBroadcastQueues) {
13203            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13204            printedAnything |= needSep;
13205        }
13206
13207        needSep = true;
13208
13209        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13210            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13211                if (needSep) {
13212                    pw.println();
13213                }
13214                needSep = true;
13215                printedAnything = true;
13216                pw.print("  Sticky broadcasts for user ");
13217                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13218                StringBuilder sb = new StringBuilder(128);
13219                for (Map.Entry<String, ArrayList<Intent>> ent
13220                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13221                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13222                    if (dumpAll) {
13223                        pw.println(":");
13224                        ArrayList<Intent> intents = ent.getValue();
13225                        final int N = intents.size();
13226                        for (int i=0; i<N; i++) {
13227                            sb.setLength(0);
13228                            sb.append("    Intent: ");
13229                            intents.get(i).toShortString(sb, false, true, false, false);
13230                            pw.println(sb.toString());
13231                            Bundle bundle = intents.get(i).getExtras();
13232                            if (bundle != null) {
13233                                pw.print("      ");
13234                                pw.println(bundle.toString());
13235                            }
13236                        }
13237                    } else {
13238                        pw.println("");
13239                    }
13240                }
13241            }
13242        }
13243
13244        if (!onlyHistory && dumpAll) {
13245            pw.println();
13246            for (BroadcastQueue queue : mBroadcastQueues) {
13247                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13248                        + queue.mBroadcastsScheduled);
13249            }
13250            pw.println("  mHandler:");
13251            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13252            needSep = true;
13253            printedAnything = true;
13254        }
13255
13256        if (!printedAnything) {
13257            pw.println("  (nothing)");
13258        }
13259    }
13260
13261    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13262            int opti, boolean dumpAll, String dumpPackage) {
13263        boolean needSep;
13264        boolean printedAnything = false;
13265
13266        ItemMatcher matcher = new ItemMatcher();
13267        matcher.build(args, opti);
13268
13269        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13270
13271        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13272        printedAnything |= needSep;
13273
13274        if (mLaunchingProviders.size() > 0) {
13275            boolean printed = false;
13276            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13277                ContentProviderRecord r = mLaunchingProviders.get(i);
13278                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13279                    continue;
13280                }
13281                if (!printed) {
13282                    if (needSep) pw.println();
13283                    needSep = true;
13284                    pw.println("  Launching content providers:");
13285                    printed = true;
13286                    printedAnything = true;
13287                }
13288                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13289                        pw.println(r);
13290            }
13291        }
13292
13293        if (mGrantedUriPermissions.size() > 0) {
13294            boolean printed = false;
13295            int dumpUid = -2;
13296            if (dumpPackage != null) {
13297                try {
13298                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13299                } catch (NameNotFoundException e) {
13300                    dumpUid = -1;
13301                }
13302            }
13303            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13304                int uid = mGrantedUriPermissions.keyAt(i);
13305                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13306                    continue;
13307                }
13308                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13309                if (!printed) {
13310                    if (needSep) pw.println();
13311                    needSep = true;
13312                    pw.println("  Granted Uri Permissions:");
13313                    printed = true;
13314                    printedAnything = true;
13315                }
13316                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13317                for (UriPermission perm : perms.values()) {
13318                    pw.print("    "); pw.println(perm);
13319                    if (dumpAll) {
13320                        perm.dump(pw, "      ");
13321                    }
13322                }
13323            }
13324        }
13325
13326        if (!printedAnything) {
13327            pw.println("  (nothing)");
13328        }
13329    }
13330
13331    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13332            int opti, boolean dumpAll, String dumpPackage) {
13333        boolean printed = false;
13334
13335        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13336
13337        if (mIntentSenderRecords.size() > 0) {
13338            Iterator<WeakReference<PendingIntentRecord>> it
13339                    = mIntentSenderRecords.values().iterator();
13340            while (it.hasNext()) {
13341                WeakReference<PendingIntentRecord> ref = it.next();
13342                PendingIntentRecord rec = ref != null ? ref.get(): null;
13343                if (dumpPackage != null && (rec == null
13344                        || !dumpPackage.equals(rec.key.packageName))) {
13345                    continue;
13346                }
13347                printed = true;
13348                if (rec != null) {
13349                    pw.print("  * "); pw.println(rec);
13350                    if (dumpAll) {
13351                        rec.dump(pw, "    ");
13352                    }
13353                } else {
13354                    pw.print("  * "); pw.println(ref);
13355                }
13356            }
13357        }
13358
13359        if (!printed) {
13360            pw.println("  (nothing)");
13361        }
13362    }
13363
13364    private static final int dumpProcessList(PrintWriter pw,
13365            ActivityManagerService service, List list,
13366            String prefix, String normalLabel, String persistentLabel,
13367            String dumpPackage) {
13368        int numPers = 0;
13369        final int N = list.size()-1;
13370        for (int i=N; i>=0; i--) {
13371            ProcessRecord r = (ProcessRecord)list.get(i);
13372            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13373                continue;
13374            }
13375            pw.println(String.format("%s%s #%2d: %s",
13376                    prefix, (r.persistent ? persistentLabel : normalLabel),
13377                    i, r.toString()));
13378            if (r.persistent) {
13379                numPers++;
13380            }
13381        }
13382        return numPers;
13383    }
13384
13385    private static final boolean dumpProcessOomList(PrintWriter pw,
13386            ActivityManagerService service, List<ProcessRecord> origList,
13387            String prefix, String normalLabel, String persistentLabel,
13388            boolean inclDetails, String dumpPackage) {
13389
13390        ArrayList<Pair<ProcessRecord, Integer>> list
13391                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13392        for (int i=0; i<origList.size(); i++) {
13393            ProcessRecord r = origList.get(i);
13394            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13395                continue;
13396            }
13397            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13398        }
13399
13400        if (list.size() <= 0) {
13401            return false;
13402        }
13403
13404        Comparator<Pair<ProcessRecord, Integer>> comparator
13405                = new Comparator<Pair<ProcessRecord, Integer>>() {
13406            @Override
13407            public int compare(Pair<ProcessRecord, Integer> object1,
13408                    Pair<ProcessRecord, Integer> object2) {
13409                if (object1.first.setAdj != object2.first.setAdj) {
13410                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13411                }
13412                if (object1.second.intValue() != object2.second.intValue()) {
13413                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13414                }
13415                return 0;
13416            }
13417        };
13418
13419        Collections.sort(list, comparator);
13420
13421        final long curRealtime = SystemClock.elapsedRealtime();
13422        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13423        final long curUptime = SystemClock.uptimeMillis();
13424        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13425
13426        for (int i=list.size()-1; i>=0; i--) {
13427            ProcessRecord r = list.get(i).first;
13428            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13429            char schedGroup;
13430            switch (r.setSchedGroup) {
13431                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13432                    schedGroup = 'B';
13433                    break;
13434                case Process.THREAD_GROUP_DEFAULT:
13435                    schedGroup = 'F';
13436                    break;
13437                default:
13438                    schedGroup = '?';
13439                    break;
13440            }
13441            char foreground;
13442            if (r.foregroundActivities) {
13443                foreground = 'A';
13444            } else if (r.foregroundServices) {
13445                foreground = 'S';
13446            } else {
13447                foreground = ' ';
13448            }
13449            String procState = ProcessList.makeProcStateString(r.curProcState);
13450            pw.print(prefix);
13451            pw.print(r.persistent ? persistentLabel : normalLabel);
13452            pw.print(" #");
13453            int num = (origList.size()-1)-list.get(i).second;
13454            if (num < 10) pw.print(' ');
13455            pw.print(num);
13456            pw.print(": ");
13457            pw.print(oomAdj);
13458            pw.print(' ');
13459            pw.print(schedGroup);
13460            pw.print('/');
13461            pw.print(foreground);
13462            pw.print('/');
13463            pw.print(procState);
13464            pw.print(" trm:");
13465            if (r.trimMemoryLevel < 10) pw.print(' ');
13466            pw.print(r.trimMemoryLevel);
13467            pw.print(' ');
13468            pw.print(r.toShortString());
13469            pw.print(" (");
13470            pw.print(r.adjType);
13471            pw.println(')');
13472            if (r.adjSource != null || r.adjTarget != null) {
13473                pw.print(prefix);
13474                pw.print("    ");
13475                if (r.adjTarget instanceof ComponentName) {
13476                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13477                } else if (r.adjTarget != null) {
13478                    pw.print(r.adjTarget.toString());
13479                } else {
13480                    pw.print("{null}");
13481                }
13482                pw.print("<=");
13483                if (r.adjSource instanceof ProcessRecord) {
13484                    pw.print("Proc{");
13485                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13486                    pw.println("}");
13487                } else if (r.adjSource != null) {
13488                    pw.println(r.adjSource.toString());
13489                } else {
13490                    pw.println("{null}");
13491                }
13492            }
13493            if (inclDetails) {
13494                pw.print(prefix);
13495                pw.print("    ");
13496                pw.print("oom: max="); pw.print(r.maxAdj);
13497                pw.print(" curRaw="); pw.print(r.curRawAdj);
13498                pw.print(" setRaw="); pw.print(r.setRawAdj);
13499                pw.print(" cur="); pw.print(r.curAdj);
13500                pw.print(" set="); pw.println(r.setAdj);
13501                pw.print(prefix);
13502                pw.print("    ");
13503                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13504                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13505                pw.print(" lastPss="); pw.print(r.lastPss);
13506                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13507                pw.print(prefix);
13508                pw.print("    ");
13509                pw.print("cached="); pw.print(r.cached);
13510                pw.print(" empty="); pw.print(r.empty);
13511                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13512
13513                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13514                    if (r.lastWakeTime != 0) {
13515                        long wtime;
13516                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13517                        synchronized (stats) {
13518                            wtime = stats.getProcessWakeTime(r.info.uid,
13519                                    r.pid, curRealtime);
13520                        }
13521                        long timeUsed = wtime - r.lastWakeTime;
13522                        pw.print(prefix);
13523                        pw.print("    ");
13524                        pw.print("keep awake over ");
13525                        TimeUtils.formatDuration(realtimeSince, pw);
13526                        pw.print(" used ");
13527                        TimeUtils.formatDuration(timeUsed, pw);
13528                        pw.print(" (");
13529                        pw.print((timeUsed*100)/realtimeSince);
13530                        pw.println("%)");
13531                    }
13532                    if (r.lastCpuTime != 0) {
13533                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13534                        pw.print(prefix);
13535                        pw.print("    ");
13536                        pw.print("run cpu over ");
13537                        TimeUtils.formatDuration(uptimeSince, pw);
13538                        pw.print(" used ");
13539                        TimeUtils.formatDuration(timeUsed, pw);
13540                        pw.print(" (");
13541                        pw.print((timeUsed*100)/uptimeSince);
13542                        pw.println("%)");
13543                    }
13544                }
13545            }
13546        }
13547        return true;
13548    }
13549
13550    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13551        ArrayList<ProcessRecord> procs;
13552        synchronized (this) {
13553            if (args != null && args.length > start
13554                    && args[start].charAt(0) != '-') {
13555                procs = new ArrayList<ProcessRecord>();
13556                int pid = -1;
13557                try {
13558                    pid = Integer.parseInt(args[start]);
13559                } catch (NumberFormatException e) {
13560                }
13561                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13562                    ProcessRecord proc = mLruProcesses.get(i);
13563                    if (proc.pid == pid) {
13564                        procs.add(proc);
13565                    } else if (proc.processName.equals(args[start])) {
13566                        procs.add(proc);
13567                    }
13568                }
13569                if (procs.size() <= 0) {
13570                    return null;
13571                }
13572            } else {
13573                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13574            }
13575        }
13576        return procs;
13577    }
13578
13579    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13580            PrintWriter pw, String[] args) {
13581        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13582        if (procs == null) {
13583            pw.println("No process found for: " + args[0]);
13584            return;
13585        }
13586
13587        long uptime = SystemClock.uptimeMillis();
13588        long realtime = SystemClock.elapsedRealtime();
13589        pw.println("Applications Graphics Acceleration Info:");
13590        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13591
13592        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13593            ProcessRecord r = procs.get(i);
13594            if (r.thread != null) {
13595                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13596                pw.flush();
13597                try {
13598                    TransferPipe tp = new TransferPipe();
13599                    try {
13600                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13601                        tp.go(fd);
13602                    } finally {
13603                        tp.kill();
13604                    }
13605                } catch (IOException e) {
13606                    pw.println("Failure while dumping the app: " + r);
13607                    pw.flush();
13608                } catch (RemoteException e) {
13609                    pw.println("Got a RemoteException while dumping the app " + r);
13610                    pw.flush();
13611                }
13612            }
13613        }
13614    }
13615
13616    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13617        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13618        if (procs == null) {
13619            pw.println("No process found for: " + args[0]);
13620            return;
13621        }
13622
13623        pw.println("Applications Database Info:");
13624
13625        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13626            ProcessRecord r = procs.get(i);
13627            if (r.thread != null) {
13628                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13629                pw.flush();
13630                try {
13631                    TransferPipe tp = new TransferPipe();
13632                    try {
13633                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13634                        tp.go(fd);
13635                    } finally {
13636                        tp.kill();
13637                    }
13638                } catch (IOException e) {
13639                    pw.println("Failure while dumping the app: " + r);
13640                    pw.flush();
13641                } catch (RemoteException e) {
13642                    pw.println("Got a RemoteException while dumping the app " + r);
13643                    pw.flush();
13644                }
13645            }
13646        }
13647    }
13648
13649    final static class MemItem {
13650        final boolean isProc;
13651        final String label;
13652        final String shortLabel;
13653        final long pss;
13654        final int id;
13655        final boolean hasActivities;
13656        ArrayList<MemItem> subitems;
13657
13658        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13659                boolean _hasActivities) {
13660            isProc = true;
13661            label = _label;
13662            shortLabel = _shortLabel;
13663            pss = _pss;
13664            id = _id;
13665            hasActivities = _hasActivities;
13666        }
13667
13668        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13669            isProc = false;
13670            label = _label;
13671            shortLabel = _shortLabel;
13672            pss = _pss;
13673            id = _id;
13674            hasActivities = false;
13675        }
13676    }
13677
13678    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13679            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13680        if (sort && !isCompact) {
13681            Collections.sort(items, new Comparator<MemItem>() {
13682                @Override
13683                public int compare(MemItem lhs, MemItem rhs) {
13684                    if (lhs.pss < rhs.pss) {
13685                        return 1;
13686                    } else if (lhs.pss > rhs.pss) {
13687                        return -1;
13688                    }
13689                    return 0;
13690                }
13691            });
13692        }
13693
13694        for (int i=0; i<items.size(); i++) {
13695            MemItem mi = items.get(i);
13696            if (!isCompact) {
13697                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13698            } else if (mi.isProc) {
13699                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13700                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13701                pw.println(mi.hasActivities ? ",a" : ",e");
13702            } else {
13703                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13704                pw.println(mi.pss);
13705            }
13706            if (mi.subitems != null) {
13707                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13708                        true, isCompact);
13709            }
13710        }
13711    }
13712
13713    // These are in KB.
13714    static final long[] DUMP_MEM_BUCKETS = new long[] {
13715        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13716        120*1024, 160*1024, 200*1024,
13717        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13718        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13719    };
13720
13721    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13722            boolean stackLike) {
13723        int start = label.lastIndexOf('.');
13724        if (start >= 0) start++;
13725        else start = 0;
13726        int end = label.length();
13727        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13728            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13729                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13730                out.append(bucket);
13731                out.append(stackLike ? "MB." : "MB ");
13732                out.append(label, start, end);
13733                return;
13734            }
13735        }
13736        out.append(memKB/1024);
13737        out.append(stackLike ? "MB." : "MB ");
13738        out.append(label, start, end);
13739    }
13740
13741    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13742            ProcessList.NATIVE_ADJ,
13743            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13744            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13745            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13746            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13747            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13748    };
13749    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13750            "Native",
13751            "System", "Persistent", "Foreground",
13752            "Visible", "Perceptible",
13753            "Heavy Weight", "Backup",
13754            "A Services", "Home",
13755            "Previous", "B Services", "Cached"
13756    };
13757    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13758            "native",
13759            "sys", "pers", "fore",
13760            "vis", "percept",
13761            "heavy", "backup",
13762            "servicea", "home",
13763            "prev", "serviceb", "cached"
13764    };
13765
13766    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13767            long realtime, boolean isCheckinRequest, boolean isCompact) {
13768        if (isCheckinRequest || isCompact) {
13769            // short checkin version
13770            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13771        } else {
13772            pw.println("Applications Memory Usage (kB):");
13773            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13774        }
13775    }
13776
13777    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13778            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13779        boolean dumpDetails = false;
13780        boolean dumpFullDetails = false;
13781        boolean dumpDalvik = false;
13782        boolean oomOnly = false;
13783        boolean isCompact = false;
13784        boolean localOnly = false;
13785
13786        int opti = 0;
13787        while (opti < args.length) {
13788            String opt = args[opti];
13789            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13790                break;
13791            }
13792            opti++;
13793            if ("-a".equals(opt)) {
13794                dumpDetails = true;
13795                dumpFullDetails = true;
13796                dumpDalvik = true;
13797            } else if ("-d".equals(opt)) {
13798                dumpDalvik = true;
13799            } else if ("-c".equals(opt)) {
13800                isCompact = true;
13801            } else if ("--oom".equals(opt)) {
13802                oomOnly = true;
13803            } else if ("--local".equals(opt)) {
13804                localOnly = true;
13805            } else if ("-h".equals(opt)) {
13806                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13807                pw.println("  -a: include all available information for each process.");
13808                pw.println("  -d: include dalvik details when dumping process details.");
13809                pw.println("  -c: dump in a compact machine-parseable representation.");
13810                pw.println("  --oom: only show processes organized by oom adj.");
13811                pw.println("  --local: only collect details locally, don't call process.");
13812                pw.println("If [process] is specified it can be the name or ");
13813                pw.println("pid of a specific process to dump.");
13814                return;
13815            } else {
13816                pw.println("Unknown argument: " + opt + "; use -h for help");
13817            }
13818        }
13819
13820        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13821        long uptime = SystemClock.uptimeMillis();
13822        long realtime = SystemClock.elapsedRealtime();
13823        final long[] tmpLong = new long[1];
13824
13825        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13826        if (procs == null) {
13827            // No Java processes.  Maybe they want to print a native process.
13828            if (args != null && args.length > opti
13829                    && args[opti].charAt(0) != '-') {
13830                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13831                        = new ArrayList<ProcessCpuTracker.Stats>();
13832                updateCpuStatsNow();
13833                int findPid = -1;
13834                try {
13835                    findPid = Integer.parseInt(args[opti]);
13836                } catch (NumberFormatException e) {
13837                }
13838                synchronized (mProcessCpuTracker) {
13839                    final int N = mProcessCpuTracker.countStats();
13840                    for (int i=0; i<N; i++) {
13841                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13842                        if (st.pid == findPid || (st.baseName != null
13843                                && st.baseName.equals(args[opti]))) {
13844                            nativeProcs.add(st);
13845                        }
13846                    }
13847                }
13848                if (nativeProcs.size() > 0) {
13849                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13850                            isCompact);
13851                    Debug.MemoryInfo mi = null;
13852                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13853                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13854                        final int pid = r.pid;
13855                        if (!isCheckinRequest && dumpDetails) {
13856                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13857                        }
13858                        if (mi == null) {
13859                            mi = new Debug.MemoryInfo();
13860                        }
13861                        if (dumpDetails || (!brief && !oomOnly)) {
13862                            Debug.getMemoryInfo(pid, mi);
13863                        } else {
13864                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13865                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13866                        }
13867                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13868                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13869                        if (isCheckinRequest) {
13870                            pw.println();
13871                        }
13872                    }
13873                    return;
13874                }
13875            }
13876            pw.println("No process found for: " + args[opti]);
13877            return;
13878        }
13879
13880        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13881            dumpDetails = true;
13882        }
13883
13884        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13885
13886        String[] innerArgs = new String[args.length-opti];
13887        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13888
13889        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13890        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13891        long nativePss=0, dalvikPss=0, otherPss=0;
13892        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13893
13894        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13895        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13896                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13897
13898        long totalPss = 0;
13899        long cachedPss = 0;
13900
13901        Debug.MemoryInfo mi = null;
13902        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13903            final ProcessRecord r = procs.get(i);
13904            final IApplicationThread thread;
13905            final int pid;
13906            final int oomAdj;
13907            final boolean hasActivities;
13908            synchronized (this) {
13909                thread = r.thread;
13910                pid = r.pid;
13911                oomAdj = r.getSetAdjWithServices();
13912                hasActivities = r.activities.size() > 0;
13913            }
13914            if (thread != null) {
13915                if (!isCheckinRequest && dumpDetails) {
13916                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13917                }
13918                if (mi == null) {
13919                    mi = new Debug.MemoryInfo();
13920                }
13921                if (dumpDetails || (!brief && !oomOnly)) {
13922                    Debug.getMemoryInfo(pid, mi);
13923                } else {
13924                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13925                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13926                }
13927                if (dumpDetails) {
13928                    if (localOnly) {
13929                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13930                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13931                        if (isCheckinRequest) {
13932                            pw.println();
13933                        }
13934                    } else {
13935                        try {
13936                            pw.flush();
13937                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13938                                    dumpDalvik, innerArgs);
13939                        } catch (RemoteException e) {
13940                            if (!isCheckinRequest) {
13941                                pw.println("Got RemoteException!");
13942                                pw.flush();
13943                            }
13944                        }
13945                    }
13946                }
13947
13948                final long myTotalPss = mi.getTotalPss();
13949                final long myTotalUss = mi.getTotalUss();
13950
13951                synchronized (this) {
13952                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13953                        // Record this for posterity if the process has been stable.
13954                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13955                    }
13956                }
13957
13958                if (!isCheckinRequest && mi != null) {
13959                    totalPss += myTotalPss;
13960                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13961                            (hasActivities ? " / activities)" : ")"),
13962                            r.processName, myTotalPss, pid, hasActivities);
13963                    procMems.add(pssItem);
13964                    procMemsMap.put(pid, pssItem);
13965
13966                    nativePss += mi.nativePss;
13967                    dalvikPss += mi.dalvikPss;
13968                    otherPss += mi.otherPss;
13969                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13970                        long mem = mi.getOtherPss(j);
13971                        miscPss[j] += mem;
13972                        otherPss -= mem;
13973                    }
13974
13975                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13976                        cachedPss += myTotalPss;
13977                    }
13978
13979                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13980                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13981                                || oomIndex == (oomPss.length-1)) {
13982                            oomPss[oomIndex] += myTotalPss;
13983                            if (oomProcs[oomIndex] == null) {
13984                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13985                            }
13986                            oomProcs[oomIndex].add(pssItem);
13987                            break;
13988                        }
13989                    }
13990                }
13991            }
13992        }
13993
13994        long nativeProcTotalPss = 0;
13995
13996        if (!isCheckinRequest && procs.size() > 1) {
13997            // If we are showing aggregations, also look for native processes to
13998            // include so that our aggregations are more accurate.
13999            updateCpuStatsNow();
14000            synchronized (mProcessCpuTracker) {
14001                final int N = mProcessCpuTracker.countStats();
14002                for (int i=0; i<N; i++) {
14003                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14004                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14005                        if (mi == null) {
14006                            mi = new Debug.MemoryInfo();
14007                        }
14008                        if (!brief && !oomOnly) {
14009                            Debug.getMemoryInfo(st.pid, mi);
14010                        } else {
14011                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14012                            mi.nativePrivateDirty = (int)tmpLong[0];
14013                        }
14014
14015                        final long myTotalPss = mi.getTotalPss();
14016                        totalPss += myTotalPss;
14017                        nativeProcTotalPss += myTotalPss;
14018
14019                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14020                                st.name, myTotalPss, st.pid, false);
14021                        procMems.add(pssItem);
14022
14023                        nativePss += mi.nativePss;
14024                        dalvikPss += mi.dalvikPss;
14025                        otherPss += mi.otherPss;
14026                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14027                            long mem = mi.getOtherPss(j);
14028                            miscPss[j] += mem;
14029                            otherPss -= mem;
14030                        }
14031                        oomPss[0] += myTotalPss;
14032                        if (oomProcs[0] == null) {
14033                            oomProcs[0] = new ArrayList<MemItem>();
14034                        }
14035                        oomProcs[0].add(pssItem);
14036                    }
14037                }
14038            }
14039
14040            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14041
14042            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14043            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14044            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14045            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14046                String label = Debug.MemoryInfo.getOtherLabel(j);
14047                catMems.add(new MemItem(label, label, miscPss[j], j));
14048            }
14049
14050            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14051            for (int j=0; j<oomPss.length; j++) {
14052                if (oomPss[j] != 0) {
14053                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14054                            : DUMP_MEM_OOM_LABEL[j];
14055                    MemItem item = new MemItem(label, label, oomPss[j],
14056                            DUMP_MEM_OOM_ADJ[j]);
14057                    item.subitems = oomProcs[j];
14058                    oomMems.add(item);
14059                }
14060            }
14061
14062            if (!brief && !oomOnly && !isCompact) {
14063                pw.println();
14064                pw.println("Total PSS by process:");
14065                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14066                pw.println();
14067            }
14068            if (!isCompact) {
14069                pw.println("Total PSS by OOM adjustment:");
14070            }
14071            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14072            if (!brief && !oomOnly) {
14073                PrintWriter out = categoryPw != null ? categoryPw : pw;
14074                if (!isCompact) {
14075                    out.println();
14076                    out.println("Total PSS by category:");
14077                }
14078                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14079            }
14080            if (!isCompact) {
14081                pw.println();
14082            }
14083            MemInfoReader memInfo = new MemInfoReader();
14084            memInfo.readMemInfo();
14085            if (nativeProcTotalPss > 0) {
14086                synchronized (this) {
14087                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14088                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14089                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14090                            nativeProcTotalPss);
14091                }
14092            }
14093            if (!brief) {
14094                if (!isCompact) {
14095                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14096                    pw.print(" kB (status ");
14097                    switch (mLastMemoryLevel) {
14098                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14099                            pw.println("normal)");
14100                            break;
14101                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14102                            pw.println("moderate)");
14103                            break;
14104                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14105                            pw.println("low)");
14106                            break;
14107                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14108                            pw.println("critical)");
14109                            break;
14110                        default:
14111                            pw.print(mLastMemoryLevel);
14112                            pw.println(")");
14113                            break;
14114                    }
14115                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14116                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14117                            pw.print(cachedPss); pw.print(" cached pss + ");
14118                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14119                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14120                } else {
14121                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14122                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14123                            + memInfo.getFreeSizeKb()); pw.print(",");
14124                    pw.println(totalPss - cachedPss);
14125                }
14126            }
14127            if (!isCompact) {
14128                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14129                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14130                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14131                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14132                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14133                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14134                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14135                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14136                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14137                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14138                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14139            }
14140            if (!brief) {
14141                if (memInfo.getZramTotalSizeKb() != 0) {
14142                    if (!isCompact) {
14143                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14144                                pw.print(" kB physical used for ");
14145                                pw.print(memInfo.getSwapTotalSizeKb()
14146                                        - memInfo.getSwapFreeSizeKb());
14147                                pw.print(" kB in swap (");
14148                                pw.print(memInfo.getSwapTotalSizeKb());
14149                                pw.println(" kB total swap)");
14150                    } else {
14151                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14152                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14153                                pw.println(memInfo.getSwapFreeSizeKb());
14154                    }
14155                }
14156                final int[] SINGLE_LONG_FORMAT = new int[] {
14157                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14158                };
14159                long[] longOut = new long[1];
14160                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14161                        SINGLE_LONG_FORMAT, null, longOut, null);
14162                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14163                longOut[0] = 0;
14164                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14165                        SINGLE_LONG_FORMAT, null, longOut, null);
14166                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14167                longOut[0] = 0;
14168                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14169                        SINGLE_LONG_FORMAT, null, longOut, null);
14170                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14171                longOut[0] = 0;
14172                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14173                        SINGLE_LONG_FORMAT, null, longOut, null);
14174                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14175                if (!isCompact) {
14176                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14177                        pw.print("      KSM: "); pw.print(sharing);
14178                                pw.print(" kB saved from shared ");
14179                                pw.print(shared); pw.println(" kB");
14180                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14181                                pw.print(voltile); pw.println(" kB volatile");
14182                    }
14183                    pw.print("   Tuning: ");
14184                    pw.print(ActivityManager.staticGetMemoryClass());
14185                    pw.print(" (large ");
14186                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14187                    pw.print("), oom ");
14188                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14189                    pw.print(" kB");
14190                    pw.print(", restore limit ");
14191                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14192                    pw.print(" kB");
14193                    if (ActivityManager.isLowRamDeviceStatic()) {
14194                        pw.print(" (low-ram)");
14195                    }
14196                    if (ActivityManager.isHighEndGfx()) {
14197                        pw.print(" (high-end-gfx)");
14198                    }
14199                    pw.println();
14200                } else {
14201                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14202                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14203                    pw.println(voltile);
14204                    pw.print("tuning,");
14205                    pw.print(ActivityManager.staticGetMemoryClass());
14206                    pw.print(',');
14207                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14208                    pw.print(',');
14209                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14210                    if (ActivityManager.isLowRamDeviceStatic()) {
14211                        pw.print(",low-ram");
14212                    }
14213                    if (ActivityManager.isHighEndGfx()) {
14214                        pw.print(",high-end-gfx");
14215                    }
14216                    pw.println();
14217                }
14218            }
14219        }
14220    }
14221
14222    /**
14223     * Searches array of arguments for the specified string
14224     * @param args array of argument strings
14225     * @param value value to search for
14226     * @return true if the value is contained in the array
14227     */
14228    private static boolean scanArgs(String[] args, String value) {
14229        if (args != null) {
14230            for (String arg : args) {
14231                if (value.equals(arg)) {
14232                    return true;
14233                }
14234            }
14235        }
14236        return false;
14237    }
14238
14239    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14240            ContentProviderRecord cpr, boolean always) {
14241        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14242
14243        if (!inLaunching || always) {
14244            synchronized (cpr) {
14245                cpr.launchingApp = null;
14246                cpr.notifyAll();
14247            }
14248            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14249            String names[] = cpr.info.authority.split(";");
14250            for (int j = 0; j < names.length; j++) {
14251                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14252            }
14253        }
14254
14255        for (int i=0; i<cpr.connections.size(); i++) {
14256            ContentProviderConnection conn = cpr.connections.get(i);
14257            if (conn.waiting) {
14258                // If this connection is waiting for the provider, then we don't
14259                // need to mess with its process unless we are always removing
14260                // or for some reason the provider is not currently launching.
14261                if (inLaunching && !always) {
14262                    continue;
14263                }
14264            }
14265            ProcessRecord capp = conn.client;
14266            conn.dead = true;
14267            if (conn.stableCount > 0) {
14268                if (!capp.persistent && capp.thread != null
14269                        && capp.pid != 0
14270                        && capp.pid != MY_PID) {
14271                    capp.kill("depends on provider "
14272                            + cpr.name.flattenToShortString()
14273                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14274                }
14275            } else if (capp.thread != null && conn.provider.provider != null) {
14276                try {
14277                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14278                } catch (RemoteException e) {
14279                }
14280                // In the protocol here, we don't expect the client to correctly
14281                // clean up this connection, we'll just remove it.
14282                cpr.connections.remove(i);
14283                conn.client.conProviders.remove(conn);
14284            }
14285        }
14286
14287        if (inLaunching && always) {
14288            mLaunchingProviders.remove(cpr);
14289        }
14290        return inLaunching;
14291    }
14292
14293    /**
14294     * Main code for cleaning up a process when it has gone away.  This is
14295     * called both as a result of the process dying, or directly when stopping
14296     * a process when running in single process mode.
14297     */
14298    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14299            boolean restarting, boolean allowRestart, int index) {
14300        if (index >= 0) {
14301            removeLruProcessLocked(app);
14302            ProcessList.remove(app.pid);
14303        }
14304
14305        mProcessesToGc.remove(app);
14306        mPendingPssProcesses.remove(app);
14307
14308        // Dismiss any open dialogs.
14309        if (app.crashDialog != null && !app.forceCrashReport) {
14310            app.crashDialog.dismiss();
14311            app.crashDialog = null;
14312        }
14313        if (app.anrDialog != null) {
14314            app.anrDialog.dismiss();
14315            app.anrDialog = null;
14316        }
14317        if (app.waitDialog != null) {
14318            app.waitDialog.dismiss();
14319            app.waitDialog = null;
14320        }
14321
14322        app.crashing = false;
14323        app.notResponding = false;
14324
14325        app.resetPackageList(mProcessStats);
14326        app.unlinkDeathRecipient();
14327        app.makeInactive(mProcessStats);
14328        app.waitingToKill = null;
14329        app.forcingToForeground = null;
14330        updateProcessForegroundLocked(app, false, false);
14331        app.foregroundActivities = false;
14332        app.hasShownUi = false;
14333        app.treatLikeActivity = false;
14334        app.hasAboveClient = false;
14335        app.hasClientActivities = false;
14336
14337        mServices.killServicesLocked(app, allowRestart);
14338
14339        boolean restart = false;
14340
14341        // Remove published content providers.
14342        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14343            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14344            final boolean always = app.bad || !allowRestart;
14345            if (removeDyingProviderLocked(app, cpr, always) || always) {
14346                // We left the provider in the launching list, need to
14347                // restart it.
14348                restart = true;
14349            }
14350
14351            cpr.provider = null;
14352            cpr.proc = null;
14353        }
14354        app.pubProviders.clear();
14355
14356        // Take care of any launching providers waiting for this process.
14357        if (checkAppInLaunchingProvidersLocked(app, false)) {
14358            restart = true;
14359        }
14360
14361        // Unregister from connected content providers.
14362        if (!app.conProviders.isEmpty()) {
14363            for (int i=0; i<app.conProviders.size(); i++) {
14364                ContentProviderConnection conn = app.conProviders.get(i);
14365                conn.provider.connections.remove(conn);
14366            }
14367            app.conProviders.clear();
14368        }
14369
14370        // At this point there may be remaining entries in mLaunchingProviders
14371        // where we were the only one waiting, so they are no longer of use.
14372        // Look for these and clean up if found.
14373        // XXX Commented out for now.  Trying to figure out a way to reproduce
14374        // the actual situation to identify what is actually going on.
14375        if (false) {
14376            for (int i=0; i<mLaunchingProviders.size(); i++) {
14377                ContentProviderRecord cpr = (ContentProviderRecord)
14378                        mLaunchingProviders.get(i);
14379                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14380                    synchronized (cpr) {
14381                        cpr.launchingApp = null;
14382                        cpr.notifyAll();
14383                    }
14384                }
14385            }
14386        }
14387
14388        skipCurrentReceiverLocked(app);
14389
14390        // Unregister any receivers.
14391        for (int i=app.receivers.size()-1; i>=0; i--) {
14392            removeReceiverLocked(app.receivers.valueAt(i));
14393        }
14394        app.receivers.clear();
14395
14396        // If the app is undergoing backup, tell the backup manager about it
14397        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14398            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14399                    + mBackupTarget.appInfo + " died during backup");
14400            try {
14401                IBackupManager bm = IBackupManager.Stub.asInterface(
14402                        ServiceManager.getService(Context.BACKUP_SERVICE));
14403                bm.agentDisconnected(app.info.packageName);
14404            } catch (RemoteException e) {
14405                // can't happen; backup manager is local
14406            }
14407        }
14408
14409        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14410            ProcessChangeItem item = mPendingProcessChanges.get(i);
14411            if (item.pid == app.pid) {
14412                mPendingProcessChanges.remove(i);
14413                mAvailProcessChanges.add(item);
14414            }
14415        }
14416        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14417
14418        // If the caller is restarting this app, then leave it in its
14419        // current lists and let the caller take care of it.
14420        if (restarting) {
14421            return;
14422        }
14423
14424        if (!app.persistent || app.isolated) {
14425            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14426                    "Removing non-persistent process during cleanup: " + app);
14427            mProcessNames.remove(app.processName, app.uid);
14428            mIsolatedProcesses.remove(app.uid);
14429            if (mHeavyWeightProcess == app) {
14430                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14431                        mHeavyWeightProcess.userId, 0));
14432                mHeavyWeightProcess = null;
14433            }
14434        } else if (!app.removed) {
14435            // This app is persistent, so we need to keep its record around.
14436            // If it is not already on the pending app list, add it there
14437            // and start a new process for it.
14438            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14439                mPersistentStartingProcesses.add(app);
14440                restart = true;
14441            }
14442        }
14443        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14444                "Clean-up removing on hold: " + app);
14445        mProcessesOnHold.remove(app);
14446
14447        if (app == mHomeProcess) {
14448            mHomeProcess = null;
14449        }
14450        if (app == mPreviousProcess) {
14451            mPreviousProcess = null;
14452        }
14453
14454        if (restart && !app.isolated) {
14455            // We have components that still need to be running in the
14456            // process, so re-launch it.
14457            mProcessNames.put(app.processName, app.uid, app);
14458            startProcessLocked(app, "restart", app.processName);
14459        } else if (app.pid > 0 && app.pid != MY_PID) {
14460            // Goodbye!
14461            boolean removed;
14462            synchronized (mPidsSelfLocked) {
14463                mPidsSelfLocked.remove(app.pid);
14464                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14465            }
14466            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14467            if (app.isolated) {
14468                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14469            }
14470            app.setPid(0);
14471        }
14472    }
14473
14474    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14475        // Look through the content providers we are waiting to have launched,
14476        // and if any run in this process then either schedule a restart of
14477        // the process or kill the client waiting for it if this process has
14478        // gone bad.
14479        int NL = mLaunchingProviders.size();
14480        boolean restart = false;
14481        for (int i=0; i<NL; i++) {
14482            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14483            if (cpr.launchingApp == app) {
14484                if (!alwaysBad && !app.bad) {
14485                    restart = true;
14486                } else {
14487                    removeDyingProviderLocked(app, cpr, true);
14488                    // cpr should have been removed from mLaunchingProviders
14489                    NL = mLaunchingProviders.size();
14490                    i--;
14491                }
14492            }
14493        }
14494        return restart;
14495    }
14496
14497    // =========================================================
14498    // SERVICES
14499    // =========================================================
14500
14501    @Override
14502    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14503            int flags) {
14504        enforceNotIsolatedCaller("getServices");
14505        synchronized (this) {
14506            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14507        }
14508    }
14509
14510    @Override
14511    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14512        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14513        synchronized (this) {
14514            return mServices.getRunningServiceControlPanelLocked(name);
14515        }
14516    }
14517
14518    @Override
14519    public ComponentName startService(IApplicationThread caller, Intent service,
14520            String resolvedType, int userId) {
14521        enforceNotIsolatedCaller("startService");
14522        // Refuse possible leaked file descriptors
14523        if (service != null && service.hasFileDescriptors() == true) {
14524            throw new IllegalArgumentException("File descriptors passed in Intent");
14525        }
14526
14527        if (DEBUG_SERVICE)
14528            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14529        synchronized(this) {
14530            final int callingPid = Binder.getCallingPid();
14531            final int callingUid = Binder.getCallingUid();
14532            final long origId = Binder.clearCallingIdentity();
14533            ComponentName res = mServices.startServiceLocked(caller, service,
14534                    resolvedType, callingPid, callingUid, userId);
14535            Binder.restoreCallingIdentity(origId);
14536            return res;
14537        }
14538    }
14539
14540    ComponentName startServiceInPackage(int uid,
14541            Intent service, String resolvedType, int userId) {
14542        synchronized(this) {
14543            if (DEBUG_SERVICE)
14544                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14545            final long origId = Binder.clearCallingIdentity();
14546            ComponentName res = mServices.startServiceLocked(null, service,
14547                    resolvedType, -1, uid, userId);
14548            Binder.restoreCallingIdentity(origId);
14549            return res;
14550        }
14551    }
14552
14553    @Override
14554    public int stopService(IApplicationThread caller, Intent service,
14555            String resolvedType, int userId) {
14556        enforceNotIsolatedCaller("stopService");
14557        // Refuse possible leaked file descriptors
14558        if (service != null && service.hasFileDescriptors() == true) {
14559            throw new IllegalArgumentException("File descriptors passed in Intent");
14560        }
14561
14562        synchronized(this) {
14563            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14564        }
14565    }
14566
14567    @Override
14568    public IBinder peekService(Intent service, String resolvedType) {
14569        enforceNotIsolatedCaller("peekService");
14570        // Refuse possible leaked file descriptors
14571        if (service != null && service.hasFileDescriptors() == true) {
14572            throw new IllegalArgumentException("File descriptors passed in Intent");
14573        }
14574        synchronized(this) {
14575            return mServices.peekServiceLocked(service, resolvedType);
14576        }
14577    }
14578
14579    @Override
14580    public boolean stopServiceToken(ComponentName className, IBinder token,
14581            int startId) {
14582        synchronized(this) {
14583            return mServices.stopServiceTokenLocked(className, token, startId);
14584        }
14585    }
14586
14587    @Override
14588    public void setServiceForeground(ComponentName className, IBinder token,
14589            int id, Notification notification, boolean removeNotification) {
14590        synchronized(this) {
14591            mServices.setServiceForegroundLocked(className, token, id, notification,
14592                    removeNotification);
14593        }
14594    }
14595
14596    @Override
14597    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14598            boolean requireFull, String name, String callerPackage) {
14599        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14600                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14601    }
14602
14603    int unsafeConvertIncomingUser(int userId) {
14604        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14605                ? mCurrentUserId : userId;
14606    }
14607
14608    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14609            int allowMode, String name, String callerPackage) {
14610        final int callingUserId = UserHandle.getUserId(callingUid);
14611        if (callingUserId == userId) {
14612            return userId;
14613        }
14614
14615        // Note that we may be accessing mCurrentUserId outside of a lock...
14616        // shouldn't be a big deal, if this is being called outside
14617        // of a locked context there is intrinsically a race with
14618        // the value the caller will receive and someone else changing it.
14619        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14620        // we will switch to the calling user if access to the current user fails.
14621        int targetUserId = unsafeConvertIncomingUser(userId);
14622
14623        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14624            final boolean allow;
14625            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14626                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14627                // If the caller has this permission, they always pass go.  And collect $200.
14628                allow = true;
14629            } else if (allowMode == ALLOW_FULL_ONLY) {
14630                // We require full access, sucks to be you.
14631                allow = false;
14632            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14633                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14634                // If the caller does not have either permission, they are always doomed.
14635                allow = false;
14636            } else if (allowMode == ALLOW_NON_FULL) {
14637                // We are blanket allowing non-full access, you lucky caller!
14638                allow = true;
14639            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14640                // We may or may not allow this depending on whether the two users are
14641                // in the same profile.
14642                synchronized (mUserProfileGroupIdsSelfLocked) {
14643                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14644                            UserInfo.NO_PROFILE_GROUP_ID);
14645                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14646                            UserInfo.NO_PROFILE_GROUP_ID);
14647                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14648                            && callingProfile == targetProfile;
14649                }
14650            } else {
14651                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14652            }
14653            if (!allow) {
14654                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14655                    // In this case, they would like to just execute as their
14656                    // owner user instead of failing.
14657                    targetUserId = callingUserId;
14658                } else {
14659                    StringBuilder builder = new StringBuilder(128);
14660                    builder.append("Permission Denial: ");
14661                    builder.append(name);
14662                    if (callerPackage != null) {
14663                        builder.append(" from ");
14664                        builder.append(callerPackage);
14665                    }
14666                    builder.append(" asks to run as user ");
14667                    builder.append(userId);
14668                    builder.append(" but is calling from user ");
14669                    builder.append(UserHandle.getUserId(callingUid));
14670                    builder.append("; this requires ");
14671                    builder.append(INTERACT_ACROSS_USERS_FULL);
14672                    if (allowMode != ALLOW_FULL_ONLY) {
14673                        builder.append(" or ");
14674                        builder.append(INTERACT_ACROSS_USERS);
14675                    }
14676                    String msg = builder.toString();
14677                    Slog.w(TAG, msg);
14678                    throw new SecurityException(msg);
14679                }
14680            }
14681        }
14682        if (!allowAll && targetUserId < 0) {
14683            throw new IllegalArgumentException(
14684                    "Call does not support special user #" + targetUserId);
14685        }
14686        // Check shell permission
14687        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14688            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14689                    targetUserId)) {
14690                throw new SecurityException("Shell does not have permission to access user "
14691                        + targetUserId + "\n " + Debug.getCallers(3));
14692            }
14693        }
14694        return targetUserId;
14695    }
14696
14697    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14698            String className, int flags) {
14699        boolean result = false;
14700        // For apps that don't have pre-defined UIDs, check for permission
14701        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14702            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14703                if (ActivityManager.checkUidPermission(
14704                        INTERACT_ACROSS_USERS,
14705                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14706                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14707                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14708                            + " requests FLAG_SINGLE_USER, but app does not hold "
14709                            + INTERACT_ACROSS_USERS;
14710                    Slog.w(TAG, msg);
14711                    throw new SecurityException(msg);
14712                }
14713                // Permission passed
14714                result = true;
14715            }
14716        } else if ("system".equals(componentProcessName)) {
14717            result = true;
14718        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14719            // Phone app and persistent apps are allowed to export singleuser providers.
14720            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14721                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14722        }
14723        if (DEBUG_MU) {
14724            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14725                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14726        }
14727        return result;
14728    }
14729
14730    /**
14731     * Checks to see if the caller is in the same app as the singleton
14732     * component, or the component is in a special app. It allows special apps
14733     * to export singleton components but prevents exporting singleton
14734     * components for regular apps.
14735     */
14736    boolean isValidSingletonCall(int callingUid, int componentUid) {
14737        int componentAppId = UserHandle.getAppId(componentUid);
14738        return UserHandle.isSameApp(callingUid, componentUid)
14739                || componentAppId == Process.SYSTEM_UID
14740                || componentAppId == Process.PHONE_UID
14741                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14742                        == PackageManager.PERMISSION_GRANTED;
14743    }
14744
14745    public int bindService(IApplicationThread caller, IBinder token,
14746            Intent service, String resolvedType,
14747            IServiceConnection connection, int flags, int userId) {
14748        enforceNotIsolatedCaller("bindService");
14749
14750        // Refuse possible leaked file descriptors
14751        if (service != null && service.hasFileDescriptors() == true) {
14752            throw new IllegalArgumentException("File descriptors passed in Intent");
14753        }
14754
14755        synchronized(this) {
14756            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14757                    connection, flags, userId);
14758        }
14759    }
14760
14761    public boolean unbindService(IServiceConnection connection) {
14762        synchronized (this) {
14763            return mServices.unbindServiceLocked(connection);
14764        }
14765    }
14766
14767    public void publishService(IBinder token, Intent intent, IBinder service) {
14768        // Refuse possible leaked file descriptors
14769        if (intent != null && intent.hasFileDescriptors() == true) {
14770            throw new IllegalArgumentException("File descriptors passed in Intent");
14771        }
14772
14773        synchronized(this) {
14774            if (!(token instanceof ServiceRecord)) {
14775                throw new IllegalArgumentException("Invalid service token");
14776            }
14777            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14778        }
14779    }
14780
14781    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14782        // Refuse possible leaked file descriptors
14783        if (intent != null && intent.hasFileDescriptors() == true) {
14784            throw new IllegalArgumentException("File descriptors passed in Intent");
14785        }
14786
14787        synchronized(this) {
14788            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14789        }
14790    }
14791
14792    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14793        synchronized(this) {
14794            if (!(token instanceof ServiceRecord)) {
14795                throw new IllegalArgumentException("Invalid service token");
14796            }
14797            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14798        }
14799    }
14800
14801    // =========================================================
14802    // BACKUP AND RESTORE
14803    // =========================================================
14804
14805    // Cause the target app to be launched if necessary and its backup agent
14806    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14807    // activity manager to announce its creation.
14808    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14809        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14810        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14811
14812        synchronized(this) {
14813            // !!! TODO: currently no check here that we're already bound
14814            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14815            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14816            synchronized (stats) {
14817                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14818            }
14819
14820            // Backup agent is now in use, its package can't be stopped.
14821            try {
14822                AppGlobals.getPackageManager().setPackageStoppedState(
14823                        app.packageName, false, UserHandle.getUserId(app.uid));
14824            } catch (RemoteException e) {
14825            } catch (IllegalArgumentException e) {
14826                Slog.w(TAG, "Failed trying to unstop package "
14827                        + app.packageName + ": " + e);
14828            }
14829
14830            BackupRecord r = new BackupRecord(ss, app, backupMode);
14831            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14832                    ? new ComponentName(app.packageName, app.backupAgentName)
14833                    : new ComponentName("android", "FullBackupAgent");
14834            // startProcessLocked() returns existing proc's record if it's already running
14835            ProcessRecord proc = startProcessLocked(app.processName, app,
14836                    false, 0, "backup", hostingName, false, false, false);
14837            if (proc == null) {
14838                Slog.e(TAG, "Unable to start backup agent process " + r);
14839                return false;
14840            }
14841
14842            r.app = proc;
14843            mBackupTarget = r;
14844            mBackupAppName = app.packageName;
14845
14846            // Try not to kill the process during backup
14847            updateOomAdjLocked(proc);
14848
14849            // If the process is already attached, schedule the creation of the backup agent now.
14850            // If it is not yet live, this will be done when it attaches to the framework.
14851            if (proc.thread != null) {
14852                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14853                try {
14854                    proc.thread.scheduleCreateBackupAgent(app,
14855                            compatibilityInfoForPackageLocked(app), backupMode);
14856                } catch (RemoteException e) {
14857                    // Will time out on the backup manager side
14858                }
14859            } else {
14860                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14861            }
14862            // Invariants: at this point, the target app process exists and the application
14863            // is either already running or in the process of coming up.  mBackupTarget and
14864            // mBackupAppName describe the app, so that when it binds back to the AM we
14865            // know that it's scheduled for a backup-agent operation.
14866        }
14867
14868        return true;
14869    }
14870
14871    @Override
14872    public void clearPendingBackup() {
14873        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14874        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14875
14876        synchronized (this) {
14877            mBackupTarget = null;
14878            mBackupAppName = null;
14879        }
14880    }
14881
14882    // A backup agent has just come up
14883    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14884        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14885                + " = " + agent);
14886
14887        synchronized(this) {
14888            if (!agentPackageName.equals(mBackupAppName)) {
14889                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14890                return;
14891            }
14892        }
14893
14894        long oldIdent = Binder.clearCallingIdentity();
14895        try {
14896            IBackupManager bm = IBackupManager.Stub.asInterface(
14897                    ServiceManager.getService(Context.BACKUP_SERVICE));
14898            bm.agentConnected(agentPackageName, agent);
14899        } catch (RemoteException e) {
14900            // can't happen; the backup manager service is local
14901        } catch (Exception e) {
14902            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14903            e.printStackTrace();
14904        } finally {
14905            Binder.restoreCallingIdentity(oldIdent);
14906        }
14907    }
14908
14909    // done with this agent
14910    public void unbindBackupAgent(ApplicationInfo appInfo) {
14911        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14912        if (appInfo == null) {
14913            Slog.w(TAG, "unbind backup agent for null app");
14914            return;
14915        }
14916
14917        synchronized(this) {
14918            try {
14919                if (mBackupAppName == null) {
14920                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14921                    return;
14922                }
14923
14924                if (!mBackupAppName.equals(appInfo.packageName)) {
14925                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14926                    return;
14927                }
14928
14929                // Not backing this app up any more; reset its OOM adjustment
14930                final ProcessRecord proc = mBackupTarget.app;
14931                updateOomAdjLocked(proc);
14932
14933                // If the app crashed during backup, 'thread' will be null here
14934                if (proc.thread != null) {
14935                    try {
14936                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14937                                compatibilityInfoForPackageLocked(appInfo));
14938                    } catch (Exception e) {
14939                        Slog.e(TAG, "Exception when unbinding backup agent:");
14940                        e.printStackTrace();
14941                    }
14942                }
14943            } finally {
14944                mBackupTarget = null;
14945                mBackupAppName = null;
14946            }
14947        }
14948    }
14949    // =========================================================
14950    // BROADCASTS
14951    // =========================================================
14952
14953    private final List getStickiesLocked(String action, IntentFilter filter,
14954            List cur, int userId) {
14955        final ContentResolver resolver = mContext.getContentResolver();
14956        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14957        if (stickies == null) {
14958            return cur;
14959        }
14960        final ArrayList<Intent> list = stickies.get(action);
14961        if (list == null) {
14962            return cur;
14963        }
14964        int N = list.size();
14965        for (int i=0; i<N; i++) {
14966            Intent intent = list.get(i);
14967            if (filter.match(resolver, intent, true, TAG) >= 0) {
14968                if (cur == null) {
14969                    cur = new ArrayList<Intent>();
14970                }
14971                cur.add(intent);
14972            }
14973        }
14974        return cur;
14975    }
14976
14977    boolean isPendingBroadcastProcessLocked(int pid) {
14978        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14979                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14980    }
14981
14982    void skipPendingBroadcastLocked(int pid) {
14983            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14984            for (BroadcastQueue queue : mBroadcastQueues) {
14985                queue.skipPendingBroadcastLocked(pid);
14986            }
14987    }
14988
14989    // The app just attached; send any pending broadcasts that it should receive
14990    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14991        boolean didSomething = false;
14992        for (BroadcastQueue queue : mBroadcastQueues) {
14993            didSomething |= queue.sendPendingBroadcastsLocked(app);
14994        }
14995        return didSomething;
14996    }
14997
14998    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14999            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15000        enforceNotIsolatedCaller("registerReceiver");
15001        int callingUid;
15002        int callingPid;
15003        synchronized(this) {
15004            ProcessRecord callerApp = null;
15005            if (caller != null) {
15006                callerApp = getRecordForAppLocked(caller);
15007                if (callerApp == null) {
15008                    throw new SecurityException(
15009                            "Unable to find app for caller " + caller
15010                            + " (pid=" + Binder.getCallingPid()
15011                            + ") when registering receiver " + receiver);
15012                }
15013                if (callerApp.info.uid != Process.SYSTEM_UID &&
15014                        !callerApp.pkgList.containsKey(callerPackage) &&
15015                        !"android".equals(callerPackage)) {
15016                    throw new SecurityException("Given caller package " + callerPackage
15017                            + " is not running in process " + callerApp);
15018                }
15019                callingUid = callerApp.info.uid;
15020                callingPid = callerApp.pid;
15021            } else {
15022                callerPackage = null;
15023                callingUid = Binder.getCallingUid();
15024                callingPid = Binder.getCallingPid();
15025            }
15026
15027            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15028                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15029
15030            List allSticky = null;
15031
15032            // Look for any matching sticky broadcasts...
15033            Iterator actions = filter.actionsIterator();
15034            if (actions != null) {
15035                while (actions.hasNext()) {
15036                    String action = (String)actions.next();
15037                    allSticky = getStickiesLocked(action, filter, allSticky,
15038                            UserHandle.USER_ALL);
15039                    allSticky = getStickiesLocked(action, filter, allSticky,
15040                            UserHandle.getUserId(callingUid));
15041                }
15042            } else {
15043                allSticky = getStickiesLocked(null, filter, allSticky,
15044                        UserHandle.USER_ALL);
15045                allSticky = getStickiesLocked(null, filter, allSticky,
15046                        UserHandle.getUserId(callingUid));
15047            }
15048
15049            // The first sticky in the list is returned directly back to
15050            // the client.
15051            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15052
15053            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15054                    + ": " + sticky);
15055
15056            if (receiver == null) {
15057                return sticky;
15058            }
15059
15060            ReceiverList rl
15061                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15062            if (rl == null) {
15063                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15064                        userId, receiver);
15065                if (rl.app != null) {
15066                    rl.app.receivers.add(rl);
15067                } else {
15068                    try {
15069                        receiver.asBinder().linkToDeath(rl, 0);
15070                    } catch (RemoteException e) {
15071                        return sticky;
15072                    }
15073                    rl.linkedToDeath = true;
15074                }
15075                mRegisteredReceivers.put(receiver.asBinder(), rl);
15076            } else if (rl.uid != callingUid) {
15077                throw new IllegalArgumentException(
15078                        "Receiver requested to register for uid " + callingUid
15079                        + " was previously registered for uid " + rl.uid);
15080            } else if (rl.pid != callingPid) {
15081                throw new IllegalArgumentException(
15082                        "Receiver requested to register for pid " + callingPid
15083                        + " was previously registered for pid " + rl.pid);
15084            } else if (rl.userId != userId) {
15085                throw new IllegalArgumentException(
15086                        "Receiver requested to register for user " + userId
15087                        + " was previously registered for user " + rl.userId);
15088            }
15089            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15090                    permission, callingUid, userId);
15091            rl.add(bf);
15092            if (!bf.debugCheck()) {
15093                Slog.w(TAG, "==> For Dynamic broadast");
15094            }
15095            mReceiverResolver.addFilter(bf);
15096
15097            // Enqueue broadcasts for all existing stickies that match
15098            // this filter.
15099            if (allSticky != null) {
15100                ArrayList receivers = new ArrayList();
15101                receivers.add(bf);
15102
15103                int N = allSticky.size();
15104                for (int i=0; i<N; i++) {
15105                    Intent intent = (Intent)allSticky.get(i);
15106                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15107                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15108                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15109                            null, null, false, true, true, -1);
15110                    queue.enqueueParallelBroadcastLocked(r);
15111                    queue.scheduleBroadcastsLocked();
15112                }
15113            }
15114
15115            return sticky;
15116        }
15117    }
15118
15119    public void unregisterReceiver(IIntentReceiver receiver) {
15120        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15121
15122        final long origId = Binder.clearCallingIdentity();
15123        try {
15124            boolean doTrim = false;
15125
15126            synchronized(this) {
15127                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15128                if (rl != null) {
15129                    if (rl.curBroadcast != null) {
15130                        BroadcastRecord r = rl.curBroadcast;
15131                        final boolean doNext = finishReceiverLocked(
15132                                receiver.asBinder(), r.resultCode, r.resultData,
15133                                r.resultExtras, r.resultAbort);
15134                        if (doNext) {
15135                            doTrim = true;
15136                            r.queue.processNextBroadcast(false);
15137                        }
15138                    }
15139
15140                    if (rl.app != null) {
15141                        rl.app.receivers.remove(rl);
15142                    }
15143                    removeReceiverLocked(rl);
15144                    if (rl.linkedToDeath) {
15145                        rl.linkedToDeath = false;
15146                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15147                    }
15148                }
15149            }
15150
15151            // If we actually concluded any broadcasts, we might now be able
15152            // to trim the recipients' apps from our working set
15153            if (doTrim) {
15154                trimApplications();
15155                return;
15156            }
15157
15158        } finally {
15159            Binder.restoreCallingIdentity(origId);
15160        }
15161    }
15162
15163    void removeReceiverLocked(ReceiverList rl) {
15164        mRegisteredReceivers.remove(rl.receiver.asBinder());
15165        int N = rl.size();
15166        for (int i=0; i<N; i++) {
15167            mReceiverResolver.removeFilter(rl.get(i));
15168        }
15169    }
15170
15171    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15172        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15173            ProcessRecord r = mLruProcesses.get(i);
15174            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15175                try {
15176                    r.thread.dispatchPackageBroadcast(cmd, packages);
15177                } catch (RemoteException ex) {
15178                }
15179            }
15180        }
15181    }
15182
15183    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15184            int callingUid, int[] users) {
15185        List<ResolveInfo> receivers = null;
15186        try {
15187            HashSet<ComponentName> singleUserReceivers = null;
15188            boolean scannedFirstReceivers = false;
15189            for (int user : users) {
15190                // Skip users that have Shell restrictions
15191                if (callingUid == Process.SHELL_UID
15192                        && getUserManagerLocked().hasUserRestriction(
15193                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15194                    continue;
15195                }
15196                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15197                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15198                if (user != 0 && newReceivers != null) {
15199                    // If this is not the primary user, we need to check for
15200                    // any receivers that should be filtered out.
15201                    for (int i=0; i<newReceivers.size(); i++) {
15202                        ResolveInfo ri = newReceivers.get(i);
15203                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15204                            newReceivers.remove(i);
15205                            i--;
15206                        }
15207                    }
15208                }
15209                if (newReceivers != null && newReceivers.size() == 0) {
15210                    newReceivers = null;
15211                }
15212                if (receivers == null) {
15213                    receivers = newReceivers;
15214                } else if (newReceivers != null) {
15215                    // We need to concatenate the additional receivers
15216                    // found with what we have do far.  This would be easy,
15217                    // but we also need to de-dup any receivers that are
15218                    // singleUser.
15219                    if (!scannedFirstReceivers) {
15220                        // Collect any single user receivers we had already retrieved.
15221                        scannedFirstReceivers = true;
15222                        for (int i=0; i<receivers.size(); i++) {
15223                            ResolveInfo ri = receivers.get(i);
15224                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15225                                ComponentName cn = new ComponentName(
15226                                        ri.activityInfo.packageName, ri.activityInfo.name);
15227                                if (singleUserReceivers == null) {
15228                                    singleUserReceivers = new HashSet<ComponentName>();
15229                                }
15230                                singleUserReceivers.add(cn);
15231                            }
15232                        }
15233                    }
15234                    // Add the new results to the existing results, tracking
15235                    // and de-dupping single user receivers.
15236                    for (int i=0; i<newReceivers.size(); i++) {
15237                        ResolveInfo ri = newReceivers.get(i);
15238                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15239                            ComponentName cn = new ComponentName(
15240                                    ri.activityInfo.packageName, ri.activityInfo.name);
15241                            if (singleUserReceivers == null) {
15242                                singleUserReceivers = new HashSet<ComponentName>();
15243                            }
15244                            if (!singleUserReceivers.contains(cn)) {
15245                                singleUserReceivers.add(cn);
15246                                receivers.add(ri);
15247                            }
15248                        } else {
15249                            receivers.add(ri);
15250                        }
15251                    }
15252                }
15253            }
15254        } catch (RemoteException ex) {
15255            // pm is in same process, this will never happen.
15256        }
15257        return receivers;
15258    }
15259
15260    private final int broadcastIntentLocked(ProcessRecord callerApp,
15261            String callerPackage, Intent intent, String resolvedType,
15262            IIntentReceiver resultTo, int resultCode, String resultData,
15263            Bundle map, String requiredPermission, int appOp,
15264            boolean ordered, boolean sticky, int callingPid, int callingUid,
15265            int userId) {
15266        intent = new Intent(intent);
15267
15268        // By default broadcasts do not go to stopped apps.
15269        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15270
15271        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15272            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15273            + " ordered=" + ordered + " userid=" + userId);
15274        if ((resultTo != null) && !ordered) {
15275            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15276        }
15277
15278        userId = handleIncomingUser(callingPid, callingUid, userId,
15279                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15280
15281        // Make sure that the user who is receiving this broadcast is started.
15282        // If not, we will just skip it.
15283
15284        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15285            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15286                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15287                Slog.w(TAG, "Skipping broadcast of " + intent
15288                        + ": user " + userId + " is stopped");
15289                return ActivityManager.BROADCAST_SUCCESS;
15290            }
15291        }
15292
15293        /*
15294         * Prevent non-system code (defined here to be non-persistent
15295         * processes) from sending protected broadcasts.
15296         */
15297        int callingAppId = UserHandle.getAppId(callingUid);
15298        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15299            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15300            || callingAppId == Process.NFC_UID || callingUid == 0) {
15301            // Always okay.
15302        } else if (callerApp == null || !callerApp.persistent) {
15303            try {
15304                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15305                        intent.getAction())) {
15306                    String msg = "Permission Denial: not allowed to send broadcast "
15307                            + intent.getAction() + " from pid="
15308                            + callingPid + ", uid=" + callingUid;
15309                    Slog.w(TAG, msg);
15310                    throw new SecurityException(msg);
15311                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15312                    // Special case for compatibility: we don't want apps to send this,
15313                    // but historically it has not been protected and apps may be using it
15314                    // to poke their own app widget.  So, instead of making it protected,
15315                    // just limit it to the caller.
15316                    if (callerApp == null) {
15317                        String msg = "Permission Denial: not allowed to send broadcast "
15318                                + intent.getAction() + " from unknown caller.";
15319                        Slog.w(TAG, msg);
15320                        throw new SecurityException(msg);
15321                    } else if (intent.getComponent() != null) {
15322                        // They are good enough to send to an explicit component...  verify
15323                        // it is being sent to the calling app.
15324                        if (!intent.getComponent().getPackageName().equals(
15325                                callerApp.info.packageName)) {
15326                            String msg = "Permission Denial: not allowed to send broadcast "
15327                                    + intent.getAction() + " to "
15328                                    + intent.getComponent().getPackageName() + " from "
15329                                    + callerApp.info.packageName;
15330                            Slog.w(TAG, msg);
15331                            throw new SecurityException(msg);
15332                        }
15333                    } else {
15334                        // Limit broadcast to their own package.
15335                        intent.setPackage(callerApp.info.packageName);
15336                    }
15337                }
15338            } catch (RemoteException e) {
15339                Slog.w(TAG, "Remote exception", e);
15340                return ActivityManager.BROADCAST_SUCCESS;
15341            }
15342        }
15343
15344        // Handle special intents: if this broadcast is from the package
15345        // manager about a package being removed, we need to remove all of
15346        // its activities from the history stack.
15347        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15348                intent.getAction());
15349        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15350                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15351                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15352                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15353                || uidRemoved) {
15354            if (checkComponentPermission(
15355                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15356                    callingPid, callingUid, -1, true)
15357                    == PackageManager.PERMISSION_GRANTED) {
15358                if (uidRemoved) {
15359                    final Bundle intentExtras = intent.getExtras();
15360                    final int uid = intentExtras != null
15361                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15362                    if (uid >= 0) {
15363                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15364                        synchronized (bs) {
15365                            bs.removeUidStatsLocked(uid);
15366                        }
15367                        mAppOpsService.uidRemoved(uid);
15368                    }
15369                } else {
15370                    // If resources are unavailable just force stop all
15371                    // those packages and flush the attribute cache as well.
15372                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15373                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15374                        if (list != null && (list.length > 0)) {
15375                            for (String pkg : list) {
15376                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15377                                        "storage unmount");
15378                            }
15379                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15380                            sendPackageBroadcastLocked(
15381                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15382                        }
15383                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15384                            intent.getAction())) {
15385                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15386                    } else {
15387                        Uri data = intent.getData();
15388                        String ssp;
15389                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15390                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15391                                    intent.getAction());
15392                            boolean fullUninstall = removed &&
15393                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15394                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15395                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15396                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15397                                        false, fullUninstall, userId,
15398                                        removed ? "pkg removed" : "pkg changed");
15399                            }
15400                            if (removed) {
15401                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15402                                        new String[] {ssp}, userId);
15403                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15404                                    mAppOpsService.packageRemoved(
15405                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15406
15407                                    // Remove all permissions granted from/to this package
15408                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15409                                }
15410                            }
15411                        }
15412                    }
15413                }
15414            } else {
15415                String msg = "Permission Denial: " + intent.getAction()
15416                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15417                        + ", uid=" + callingUid + ")"
15418                        + " requires "
15419                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15420                Slog.w(TAG, msg);
15421                throw new SecurityException(msg);
15422            }
15423
15424        // Special case for adding a package: by default turn on compatibility
15425        // mode.
15426        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15427            Uri data = intent.getData();
15428            String ssp;
15429            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15430                mCompatModePackages.handlePackageAddedLocked(ssp,
15431                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15432            }
15433        }
15434
15435        /*
15436         * If this is the time zone changed action, queue up a message that will reset the timezone
15437         * of all currently running processes. This message will get queued up before the broadcast
15438         * happens.
15439         */
15440        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15441            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15442        }
15443
15444        /*
15445         * If the user set the time, let all running processes know.
15446         */
15447        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15448            final int is24Hour = intent.getBooleanExtra(
15449                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15450            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15451            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15452            synchronized (stats) {
15453                stats.noteCurrentTimeChangedLocked();
15454            }
15455        }
15456
15457        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15458            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15459        }
15460
15461        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15462            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15463            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15464        }
15465
15466        // Add to the sticky list if requested.
15467        if (sticky) {
15468            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15469                    callingPid, callingUid)
15470                    != PackageManager.PERMISSION_GRANTED) {
15471                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15472                        + callingPid + ", uid=" + callingUid
15473                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15474                Slog.w(TAG, msg);
15475                throw new SecurityException(msg);
15476            }
15477            if (requiredPermission != null) {
15478                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15479                        + " and enforce permission " + requiredPermission);
15480                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15481            }
15482            if (intent.getComponent() != null) {
15483                throw new SecurityException(
15484                        "Sticky broadcasts can't target a specific component");
15485            }
15486            // We use userId directly here, since the "all" target is maintained
15487            // as a separate set of sticky broadcasts.
15488            if (userId != UserHandle.USER_ALL) {
15489                // But first, if this is not a broadcast to all users, then
15490                // make sure it doesn't conflict with an existing broadcast to
15491                // all users.
15492                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15493                        UserHandle.USER_ALL);
15494                if (stickies != null) {
15495                    ArrayList<Intent> list = stickies.get(intent.getAction());
15496                    if (list != null) {
15497                        int N = list.size();
15498                        int i;
15499                        for (i=0; i<N; i++) {
15500                            if (intent.filterEquals(list.get(i))) {
15501                                throw new IllegalArgumentException(
15502                                        "Sticky broadcast " + intent + " for user "
15503                                        + userId + " conflicts with existing global broadcast");
15504                            }
15505                        }
15506                    }
15507                }
15508            }
15509            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15510            if (stickies == null) {
15511                stickies = new ArrayMap<String, ArrayList<Intent>>();
15512                mStickyBroadcasts.put(userId, stickies);
15513            }
15514            ArrayList<Intent> list = stickies.get(intent.getAction());
15515            if (list == null) {
15516                list = new ArrayList<Intent>();
15517                stickies.put(intent.getAction(), list);
15518            }
15519            int N = list.size();
15520            int i;
15521            for (i=0; i<N; i++) {
15522                if (intent.filterEquals(list.get(i))) {
15523                    // This sticky already exists, replace it.
15524                    list.set(i, new Intent(intent));
15525                    break;
15526                }
15527            }
15528            if (i >= N) {
15529                list.add(new Intent(intent));
15530            }
15531        }
15532
15533        int[] users;
15534        if (userId == UserHandle.USER_ALL) {
15535            // Caller wants broadcast to go to all started users.
15536            users = mStartedUserArray;
15537        } else {
15538            // Caller wants broadcast to go to one specific user.
15539            users = new int[] {userId};
15540        }
15541
15542        // Figure out who all will receive this broadcast.
15543        List receivers = null;
15544        List<BroadcastFilter> registeredReceivers = null;
15545        // Need to resolve the intent to interested receivers...
15546        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15547                 == 0) {
15548            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15549        }
15550        if (intent.getComponent() == null) {
15551            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15552                // Query one target user at a time, excluding shell-restricted users
15553                UserManagerService ums = getUserManagerLocked();
15554                for (int i = 0; i < users.length; i++) {
15555                    if (ums.hasUserRestriction(
15556                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15557                        continue;
15558                    }
15559                    List<BroadcastFilter> registeredReceiversForUser =
15560                            mReceiverResolver.queryIntent(intent,
15561                                    resolvedType, false, users[i]);
15562                    if (registeredReceivers == null) {
15563                        registeredReceivers = registeredReceiversForUser;
15564                    } else if (registeredReceiversForUser != null) {
15565                        registeredReceivers.addAll(registeredReceiversForUser);
15566                    }
15567                }
15568            } else {
15569                registeredReceivers = mReceiverResolver.queryIntent(intent,
15570                        resolvedType, false, userId);
15571            }
15572        }
15573
15574        final boolean replacePending =
15575                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15576
15577        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15578                + " replacePending=" + replacePending);
15579
15580        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15581        if (!ordered && NR > 0) {
15582            // If we are not serializing this broadcast, then send the
15583            // registered receivers separately so they don't wait for the
15584            // components to be launched.
15585            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15586            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15587                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15588                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15589                    ordered, sticky, false, userId);
15590            if (DEBUG_BROADCAST) Slog.v(
15591                    TAG, "Enqueueing parallel broadcast " + r);
15592            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15593            if (!replaced) {
15594                queue.enqueueParallelBroadcastLocked(r);
15595                queue.scheduleBroadcastsLocked();
15596            }
15597            registeredReceivers = null;
15598            NR = 0;
15599        }
15600
15601        // Merge into one list.
15602        int ir = 0;
15603        if (receivers != null) {
15604            // A special case for PACKAGE_ADDED: do not allow the package
15605            // being added to see this broadcast.  This prevents them from
15606            // using this as a back door to get run as soon as they are
15607            // installed.  Maybe in the future we want to have a special install
15608            // broadcast or such for apps, but we'd like to deliberately make
15609            // this decision.
15610            String skipPackages[] = null;
15611            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15612                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15613                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15614                Uri data = intent.getData();
15615                if (data != null) {
15616                    String pkgName = data.getSchemeSpecificPart();
15617                    if (pkgName != null) {
15618                        skipPackages = new String[] { pkgName };
15619                    }
15620                }
15621            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15622                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15623            }
15624            if (skipPackages != null && (skipPackages.length > 0)) {
15625                for (String skipPackage : skipPackages) {
15626                    if (skipPackage != null) {
15627                        int NT = receivers.size();
15628                        for (int it=0; it<NT; it++) {
15629                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15630                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15631                                receivers.remove(it);
15632                                it--;
15633                                NT--;
15634                            }
15635                        }
15636                    }
15637                }
15638            }
15639
15640            int NT = receivers != null ? receivers.size() : 0;
15641            int it = 0;
15642            ResolveInfo curt = null;
15643            BroadcastFilter curr = null;
15644            while (it < NT && ir < NR) {
15645                if (curt == null) {
15646                    curt = (ResolveInfo)receivers.get(it);
15647                }
15648                if (curr == null) {
15649                    curr = registeredReceivers.get(ir);
15650                }
15651                if (curr.getPriority() >= curt.priority) {
15652                    // Insert this broadcast record into the final list.
15653                    receivers.add(it, curr);
15654                    ir++;
15655                    curr = null;
15656                    it++;
15657                    NT++;
15658                } else {
15659                    // Skip to the next ResolveInfo in the final list.
15660                    it++;
15661                    curt = null;
15662                }
15663            }
15664        }
15665        while (ir < NR) {
15666            if (receivers == null) {
15667                receivers = new ArrayList();
15668            }
15669            receivers.add(registeredReceivers.get(ir));
15670            ir++;
15671        }
15672
15673        if ((receivers != null && receivers.size() > 0)
15674                || resultTo != null) {
15675            BroadcastQueue queue = broadcastQueueForIntent(intent);
15676            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15677                    callerPackage, callingPid, callingUid, resolvedType,
15678                    requiredPermission, appOp, receivers, resultTo, resultCode,
15679                    resultData, map, ordered, sticky, false, userId);
15680            if (DEBUG_BROADCAST) Slog.v(
15681                    TAG, "Enqueueing ordered broadcast " + r
15682                    + ": prev had " + queue.mOrderedBroadcasts.size());
15683            if (DEBUG_BROADCAST) {
15684                int seq = r.intent.getIntExtra("seq", -1);
15685                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15686            }
15687            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15688            if (!replaced) {
15689                queue.enqueueOrderedBroadcastLocked(r);
15690                queue.scheduleBroadcastsLocked();
15691            }
15692        }
15693
15694        return ActivityManager.BROADCAST_SUCCESS;
15695    }
15696
15697    final Intent verifyBroadcastLocked(Intent intent) {
15698        // Refuse possible leaked file descriptors
15699        if (intent != null && intent.hasFileDescriptors() == true) {
15700            throw new IllegalArgumentException("File descriptors passed in Intent");
15701        }
15702
15703        int flags = intent.getFlags();
15704
15705        if (!mProcessesReady) {
15706            // if the caller really truly claims to know what they're doing, go
15707            // ahead and allow the broadcast without launching any receivers
15708            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15709                intent = new Intent(intent);
15710                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15711            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15712                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15713                        + " before boot completion");
15714                throw new IllegalStateException("Cannot broadcast before boot completed");
15715            }
15716        }
15717
15718        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15719            throw new IllegalArgumentException(
15720                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15721        }
15722
15723        return intent;
15724    }
15725
15726    public final int broadcastIntent(IApplicationThread caller,
15727            Intent intent, String resolvedType, IIntentReceiver resultTo,
15728            int resultCode, String resultData, Bundle map,
15729            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15730        enforceNotIsolatedCaller("broadcastIntent");
15731        synchronized(this) {
15732            intent = verifyBroadcastLocked(intent);
15733
15734            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15735            final int callingPid = Binder.getCallingPid();
15736            final int callingUid = Binder.getCallingUid();
15737            final long origId = Binder.clearCallingIdentity();
15738            int res = broadcastIntentLocked(callerApp,
15739                    callerApp != null ? callerApp.info.packageName : null,
15740                    intent, resolvedType, resultTo,
15741                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15742                    callingPid, callingUid, userId);
15743            Binder.restoreCallingIdentity(origId);
15744            return res;
15745        }
15746    }
15747
15748    int broadcastIntentInPackage(String packageName, int uid,
15749            Intent intent, String resolvedType, IIntentReceiver resultTo,
15750            int resultCode, String resultData, Bundle map,
15751            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15752        synchronized(this) {
15753            intent = verifyBroadcastLocked(intent);
15754
15755            final long origId = Binder.clearCallingIdentity();
15756            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15757                    resultTo, resultCode, resultData, map, requiredPermission,
15758                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15759            Binder.restoreCallingIdentity(origId);
15760            return res;
15761        }
15762    }
15763
15764    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15765        // Refuse possible leaked file descriptors
15766        if (intent != null && intent.hasFileDescriptors() == true) {
15767            throw new IllegalArgumentException("File descriptors passed in Intent");
15768        }
15769
15770        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15771                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15772
15773        synchronized(this) {
15774            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15775                    != PackageManager.PERMISSION_GRANTED) {
15776                String msg = "Permission Denial: unbroadcastIntent() from pid="
15777                        + Binder.getCallingPid()
15778                        + ", uid=" + Binder.getCallingUid()
15779                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15780                Slog.w(TAG, msg);
15781                throw new SecurityException(msg);
15782            }
15783            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15784            if (stickies != null) {
15785                ArrayList<Intent> list = stickies.get(intent.getAction());
15786                if (list != null) {
15787                    int N = list.size();
15788                    int i;
15789                    for (i=0; i<N; i++) {
15790                        if (intent.filterEquals(list.get(i))) {
15791                            list.remove(i);
15792                            break;
15793                        }
15794                    }
15795                    if (list.size() <= 0) {
15796                        stickies.remove(intent.getAction());
15797                    }
15798                }
15799                if (stickies.size() <= 0) {
15800                    mStickyBroadcasts.remove(userId);
15801                }
15802            }
15803        }
15804    }
15805
15806    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15807            String resultData, Bundle resultExtras, boolean resultAbort) {
15808        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15809        if (r == null) {
15810            Slog.w(TAG, "finishReceiver called but not found on queue");
15811            return false;
15812        }
15813
15814        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15815    }
15816
15817    void backgroundServicesFinishedLocked(int userId) {
15818        for (BroadcastQueue queue : mBroadcastQueues) {
15819            queue.backgroundServicesFinishedLocked(userId);
15820        }
15821    }
15822
15823    public void finishReceiver(IBinder who, int resultCode, String resultData,
15824            Bundle resultExtras, boolean resultAbort) {
15825        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15826
15827        // Refuse possible leaked file descriptors
15828        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15829            throw new IllegalArgumentException("File descriptors passed in Bundle");
15830        }
15831
15832        final long origId = Binder.clearCallingIdentity();
15833        try {
15834            boolean doNext = false;
15835            BroadcastRecord r;
15836
15837            synchronized(this) {
15838                r = broadcastRecordForReceiverLocked(who);
15839                if (r != null) {
15840                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15841                        resultData, resultExtras, resultAbort, true);
15842                }
15843            }
15844
15845            if (doNext) {
15846                r.queue.processNextBroadcast(false);
15847            }
15848            trimApplications();
15849        } finally {
15850            Binder.restoreCallingIdentity(origId);
15851        }
15852    }
15853
15854    // =========================================================
15855    // INSTRUMENTATION
15856    // =========================================================
15857
15858    public boolean startInstrumentation(ComponentName className,
15859            String profileFile, int flags, Bundle arguments,
15860            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15861            int userId, String abiOverride) {
15862        enforceNotIsolatedCaller("startInstrumentation");
15863        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15864                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15865        // Refuse possible leaked file descriptors
15866        if (arguments != null && arguments.hasFileDescriptors()) {
15867            throw new IllegalArgumentException("File descriptors passed in Bundle");
15868        }
15869
15870        synchronized(this) {
15871            InstrumentationInfo ii = null;
15872            ApplicationInfo ai = null;
15873            try {
15874                ii = mContext.getPackageManager().getInstrumentationInfo(
15875                    className, STOCK_PM_FLAGS);
15876                ai = AppGlobals.getPackageManager().getApplicationInfo(
15877                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15878            } catch (PackageManager.NameNotFoundException e) {
15879            } catch (RemoteException e) {
15880            }
15881            if (ii == null) {
15882                reportStartInstrumentationFailure(watcher, className,
15883                        "Unable to find instrumentation info for: " + className);
15884                return false;
15885            }
15886            if (ai == null) {
15887                reportStartInstrumentationFailure(watcher, className,
15888                        "Unable to find instrumentation target package: " + ii.targetPackage);
15889                return false;
15890            }
15891
15892            int match = mContext.getPackageManager().checkSignatures(
15893                    ii.targetPackage, ii.packageName);
15894            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15895                String msg = "Permission Denial: starting instrumentation "
15896                        + className + " from pid="
15897                        + Binder.getCallingPid()
15898                        + ", uid=" + Binder.getCallingPid()
15899                        + " not allowed because package " + ii.packageName
15900                        + " does not have a signature matching the target "
15901                        + ii.targetPackage;
15902                reportStartInstrumentationFailure(watcher, className, msg);
15903                throw new SecurityException(msg);
15904            }
15905
15906            final long origId = Binder.clearCallingIdentity();
15907            // Instrumentation can kill and relaunch even persistent processes
15908            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15909                    "start instr");
15910            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15911            app.instrumentationClass = className;
15912            app.instrumentationInfo = ai;
15913            app.instrumentationProfileFile = profileFile;
15914            app.instrumentationArguments = arguments;
15915            app.instrumentationWatcher = watcher;
15916            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15917            app.instrumentationResultClass = className;
15918            Binder.restoreCallingIdentity(origId);
15919        }
15920
15921        return true;
15922    }
15923
15924    /**
15925     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15926     * error to the logs, but if somebody is watching, send the report there too.  This enables
15927     * the "am" command to report errors with more information.
15928     *
15929     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15930     * @param cn The component name of the instrumentation.
15931     * @param report The error report.
15932     */
15933    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15934            ComponentName cn, String report) {
15935        Slog.w(TAG, report);
15936        try {
15937            if (watcher != null) {
15938                Bundle results = new Bundle();
15939                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15940                results.putString("Error", report);
15941                watcher.instrumentationStatus(cn, -1, results);
15942            }
15943        } catch (RemoteException e) {
15944            Slog.w(TAG, e);
15945        }
15946    }
15947
15948    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15949        if (app.instrumentationWatcher != null) {
15950            try {
15951                // NOTE:  IInstrumentationWatcher *must* be oneway here
15952                app.instrumentationWatcher.instrumentationFinished(
15953                    app.instrumentationClass,
15954                    resultCode,
15955                    results);
15956            } catch (RemoteException e) {
15957            }
15958        }
15959        if (app.instrumentationUiAutomationConnection != null) {
15960            try {
15961                app.instrumentationUiAutomationConnection.shutdown();
15962            } catch (RemoteException re) {
15963                /* ignore */
15964            }
15965            // Only a UiAutomation can set this flag and now that
15966            // it is finished we make sure it is reset to its default.
15967            mUserIsMonkey = false;
15968        }
15969        app.instrumentationWatcher = null;
15970        app.instrumentationUiAutomationConnection = null;
15971        app.instrumentationClass = null;
15972        app.instrumentationInfo = null;
15973        app.instrumentationProfileFile = null;
15974        app.instrumentationArguments = null;
15975
15976        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15977                "finished inst");
15978    }
15979
15980    public void finishInstrumentation(IApplicationThread target,
15981            int resultCode, Bundle results) {
15982        int userId = UserHandle.getCallingUserId();
15983        // Refuse possible leaked file descriptors
15984        if (results != null && results.hasFileDescriptors()) {
15985            throw new IllegalArgumentException("File descriptors passed in Intent");
15986        }
15987
15988        synchronized(this) {
15989            ProcessRecord app = getRecordForAppLocked(target);
15990            if (app == null) {
15991                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15992                return;
15993            }
15994            final long origId = Binder.clearCallingIdentity();
15995            finishInstrumentationLocked(app, resultCode, results);
15996            Binder.restoreCallingIdentity(origId);
15997        }
15998    }
15999
16000    // =========================================================
16001    // CONFIGURATION
16002    // =========================================================
16003
16004    public ConfigurationInfo getDeviceConfigurationInfo() {
16005        ConfigurationInfo config = new ConfigurationInfo();
16006        synchronized (this) {
16007            config.reqTouchScreen = mConfiguration.touchscreen;
16008            config.reqKeyboardType = mConfiguration.keyboard;
16009            config.reqNavigation = mConfiguration.navigation;
16010            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16011                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16012                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16013            }
16014            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16015                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16016                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16017            }
16018            config.reqGlEsVersion = GL_ES_VERSION;
16019        }
16020        return config;
16021    }
16022
16023    ActivityStack getFocusedStack() {
16024        return mStackSupervisor.getFocusedStack();
16025    }
16026
16027    public Configuration getConfiguration() {
16028        Configuration ci;
16029        synchronized(this) {
16030            ci = new Configuration(mConfiguration);
16031        }
16032        return ci;
16033    }
16034
16035    public void updatePersistentConfiguration(Configuration values) {
16036        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16037                "updateConfiguration()");
16038        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16039                "updateConfiguration()");
16040        if (values == null) {
16041            throw new NullPointerException("Configuration must not be null");
16042        }
16043
16044        synchronized(this) {
16045            final long origId = Binder.clearCallingIdentity();
16046            updateConfigurationLocked(values, null, true, false);
16047            Binder.restoreCallingIdentity(origId);
16048        }
16049    }
16050
16051    public void updateConfiguration(Configuration values) {
16052        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16053                "updateConfiguration()");
16054
16055        synchronized(this) {
16056            if (values == null && mWindowManager != null) {
16057                // sentinel: fetch the current configuration from the window manager
16058                values = mWindowManager.computeNewConfiguration();
16059            }
16060
16061            if (mWindowManager != null) {
16062                mProcessList.applyDisplaySize(mWindowManager);
16063            }
16064
16065            final long origId = Binder.clearCallingIdentity();
16066            if (values != null) {
16067                Settings.System.clearConfiguration(values);
16068            }
16069            updateConfigurationLocked(values, null, false, false);
16070            Binder.restoreCallingIdentity(origId);
16071        }
16072    }
16073
16074    /**
16075     * Do either or both things: (1) change the current configuration, and (2)
16076     * make sure the given activity is running with the (now) current
16077     * configuration.  Returns true if the activity has been left running, or
16078     * false if <var>starting</var> is being destroyed to match the new
16079     * configuration.
16080     * @param persistent TODO
16081     */
16082    boolean updateConfigurationLocked(Configuration values,
16083            ActivityRecord starting, boolean persistent, boolean initLocale) {
16084        int changes = 0;
16085
16086        if (values != null) {
16087            Configuration newConfig = new Configuration(mConfiguration);
16088            changes = newConfig.updateFrom(values);
16089            if (changes != 0) {
16090                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16091                    Slog.i(TAG, "Updating configuration to: " + values);
16092                }
16093
16094                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16095
16096                if (values.locale != null && !initLocale) {
16097                    saveLocaleLocked(values.locale,
16098                                     !values.locale.equals(mConfiguration.locale),
16099                                     values.userSetLocale);
16100                }
16101
16102                mConfigurationSeq++;
16103                if (mConfigurationSeq <= 0) {
16104                    mConfigurationSeq = 1;
16105                }
16106                newConfig.seq = mConfigurationSeq;
16107                mConfiguration = newConfig;
16108                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16109                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16110                //mUsageStatsService.noteStartConfig(newConfig);
16111
16112                final Configuration configCopy = new Configuration(mConfiguration);
16113
16114                // TODO: If our config changes, should we auto dismiss any currently
16115                // showing dialogs?
16116                mShowDialogs = shouldShowDialogs(newConfig);
16117
16118                AttributeCache ac = AttributeCache.instance();
16119                if (ac != null) {
16120                    ac.updateConfiguration(configCopy);
16121                }
16122
16123                // Make sure all resources in our process are updated
16124                // right now, so that anyone who is going to retrieve
16125                // resource values after we return will be sure to get
16126                // the new ones.  This is especially important during
16127                // boot, where the first config change needs to guarantee
16128                // all resources have that config before following boot
16129                // code is executed.
16130                mSystemThread.applyConfigurationToResources(configCopy);
16131
16132                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16133                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16134                    msg.obj = new Configuration(configCopy);
16135                    mHandler.sendMessage(msg);
16136                }
16137
16138                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16139                    ProcessRecord app = mLruProcesses.get(i);
16140                    try {
16141                        if (app.thread != null) {
16142                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16143                                    + app.processName + " new config " + mConfiguration);
16144                            app.thread.scheduleConfigurationChanged(configCopy);
16145                        }
16146                    } catch (Exception e) {
16147                    }
16148                }
16149                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16150                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16151                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16152                        | Intent.FLAG_RECEIVER_FOREGROUND);
16153                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16154                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16155                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16156                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16157                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16158                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16159                    broadcastIntentLocked(null, null, intent,
16160                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16161                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16162                }
16163            }
16164        }
16165
16166        boolean kept = true;
16167        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16168        // mainStack is null during startup.
16169        if (mainStack != null) {
16170            if (changes != 0 && starting == null) {
16171                // If the configuration changed, and the caller is not already
16172                // in the process of starting an activity, then find the top
16173                // activity to check if its configuration needs to change.
16174                starting = mainStack.topRunningActivityLocked(null);
16175            }
16176
16177            if (starting != null) {
16178                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16179                // And we need to make sure at this point that all other activities
16180                // are made visible with the correct configuration.
16181                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16182            }
16183        }
16184
16185        if (values != null && mWindowManager != null) {
16186            mWindowManager.setNewConfiguration(mConfiguration);
16187        }
16188
16189        return kept;
16190    }
16191
16192    /**
16193     * Decide based on the configuration whether we should shouw the ANR,
16194     * crash, etc dialogs.  The idea is that if there is no affordnace to
16195     * press the on-screen buttons, we shouldn't show the dialog.
16196     *
16197     * A thought: SystemUI might also want to get told about this, the Power
16198     * dialog / global actions also might want different behaviors.
16199     */
16200    private static final boolean shouldShowDialogs(Configuration config) {
16201        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16202                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16203    }
16204
16205    /**
16206     * Save the locale.  You must be inside a synchronized (this) block.
16207     */
16208    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16209        if(isDiff) {
16210            SystemProperties.set("user.language", l.getLanguage());
16211            SystemProperties.set("user.region", l.getCountry());
16212        }
16213
16214        if(isPersist) {
16215            SystemProperties.set("persist.sys.language", l.getLanguage());
16216            SystemProperties.set("persist.sys.country", l.getCountry());
16217            SystemProperties.set("persist.sys.localevar", l.getVariant());
16218        }
16219    }
16220
16221    @Override
16222    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16223        synchronized (this) {
16224            ActivityRecord srec = ActivityRecord.forToken(token);
16225            if (srec.task != null && srec.task.stack != null) {
16226                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16227            }
16228        }
16229        return false;
16230    }
16231
16232    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16233            Intent resultData) {
16234
16235        synchronized (this) {
16236            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16237            if (stack != null) {
16238                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16239            }
16240            return false;
16241        }
16242    }
16243
16244    public int getLaunchedFromUid(IBinder activityToken) {
16245        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16246        if (srec == null) {
16247            return -1;
16248        }
16249        return srec.launchedFromUid;
16250    }
16251
16252    public String getLaunchedFromPackage(IBinder activityToken) {
16253        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16254        if (srec == null) {
16255            return null;
16256        }
16257        return srec.launchedFromPackage;
16258    }
16259
16260    // =========================================================
16261    // LIFETIME MANAGEMENT
16262    // =========================================================
16263
16264    // Returns which broadcast queue the app is the current [or imminent] receiver
16265    // on, or 'null' if the app is not an active broadcast recipient.
16266    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16267        BroadcastRecord r = app.curReceiver;
16268        if (r != null) {
16269            return r.queue;
16270        }
16271
16272        // It's not the current receiver, but it might be starting up to become one
16273        synchronized (this) {
16274            for (BroadcastQueue queue : mBroadcastQueues) {
16275                r = queue.mPendingBroadcast;
16276                if (r != null && r.curApp == app) {
16277                    // found it; report which queue it's in
16278                    return queue;
16279                }
16280            }
16281        }
16282
16283        return null;
16284    }
16285
16286    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16287            boolean doingAll, long now) {
16288        if (mAdjSeq == app.adjSeq) {
16289            // This adjustment has already been computed.
16290            return app.curRawAdj;
16291        }
16292
16293        if (app.thread == null) {
16294            app.adjSeq = mAdjSeq;
16295            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16296            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16297            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16298        }
16299
16300        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16301        app.adjSource = null;
16302        app.adjTarget = null;
16303        app.empty = false;
16304        app.cached = false;
16305
16306        final int activitiesSize = app.activities.size();
16307
16308        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16309            // The max adjustment doesn't allow this app to be anything
16310            // below foreground, so it is not worth doing work for it.
16311            app.adjType = "fixed";
16312            app.adjSeq = mAdjSeq;
16313            app.curRawAdj = app.maxAdj;
16314            app.foregroundActivities = false;
16315            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16316            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16317            // System processes can do UI, and when they do we want to have
16318            // them trim their memory after the user leaves the UI.  To
16319            // facilitate this, here we need to determine whether or not it
16320            // is currently showing UI.
16321            app.systemNoUi = true;
16322            if (app == TOP_APP) {
16323                app.systemNoUi = false;
16324            } else if (activitiesSize > 0) {
16325                for (int j = 0; j < activitiesSize; j++) {
16326                    final ActivityRecord r = app.activities.get(j);
16327                    if (r.visible) {
16328                        app.systemNoUi = false;
16329                    }
16330                }
16331            }
16332            if (!app.systemNoUi) {
16333                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16334            }
16335            return (app.curAdj=app.maxAdj);
16336        }
16337
16338        app.systemNoUi = false;
16339
16340        // Determine the importance of the process, starting with most
16341        // important to least, and assign an appropriate OOM adjustment.
16342        int adj;
16343        int schedGroup;
16344        int procState;
16345        boolean foregroundActivities = false;
16346        BroadcastQueue queue;
16347        if (app == TOP_APP) {
16348            // The last app on the list is the foreground app.
16349            adj = ProcessList.FOREGROUND_APP_ADJ;
16350            schedGroup = Process.THREAD_GROUP_DEFAULT;
16351            app.adjType = "top-activity";
16352            foregroundActivities = true;
16353            procState = ActivityManager.PROCESS_STATE_TOP;
16354        } else if (app.instrumentationClass != null) {
16355            // Don't want to kill running instrumentation.
16356            adj = ProcessList.FOREGROUND_APP_ADJ;
16357            schedGroup = Process.THREAD_GROUP_DEFAULT;
16358            app.adjType = "instrumentation";
16359            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16360        } else if ((queue = isReceivingBroadcast(app)) != null) {
16361            // An app that is currently receiving a broadcast also
16362            // counts as being in the foreground for OOM killer purposes.
16363            // It's placed in a sched group based on the nature of the
16364            // broadcast as reflected by which queue it's active in.
16365            adj = ProcessList.FOREGROUND_APP_ADJ;
16366            schedGroup = (queue == mFgBroadcastQueue)
16367                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16368            app.adjType = "broadcast";
16369            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16370        } else if (app.executingServices.size() > 0) {
16371            // An app that is currently executing a service callback also
16372            // counts as being in the foreground.
16373            adj = ProcessList.FOREGROUND_APP_ADJ;
16374            schedGroup = app.execServicesFg ?
16375                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16376            app.adjType = "exec-service";
16377            procState = ActivityManager.PROCESS_STATE_SERVICE;
16378            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16379        } else {
16380            // As far as we know the process is empty.  We may change our mind later.
16381            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16382            // At this point we don't actually know the adjustment.  Use the cached adj
16383            // value that the caller wants us to.
16384            adj = cachedAdj;
16385            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16386            app.cached = true;
16387            app.empty = true;
16388            app.adjType = "cch-empty";
16389        }
16390
16391        // Examine all activities if not already foreground.
16392        if (!foregroundActivities && activitiesSize > 0) {
16393            for (int j = 0; j < activitiesSize; j++) {
16394                final ActivityRecord r = app.activities.get(j);
16395                if (r.app != app) {
16396                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16397                            + app + "?!?");
16398                    continue;
16399                }
16400                if (r.visible) {
16401                    // App has a visible activity; only upgrade adjustment.
16402                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16403                        adj = ProcessList.VISIBLE_APP_ADJ;
16404                        app.adjType = "visible";
16405                    }
16406                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16407                        procState = ActivityManager.PROCESS_STATE_TOP;
16408                    }
16409                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16410                    app.cached = false;
16411                    app.empty = false;
16412                    foregroundActivities = true;
16413                    break;
16414                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16415                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16416                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16417                        app.adjType = "pausing";
16418                    }
16419                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16420                        procState = ActivityManager.PROCESS_STATE_TOP;
16421                    }
16422                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16423                    app.cached = false;
16424                    app.empty = false;
16425                    foregroundActivities = true;
16426                } else if (r.state == ActivityState.STOPPING) {
16427                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16428                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16429                        app.adjType = "stopping";
16430                    }
16431                    // For the process state, we will at this point consider the
16432                    // process to be cached.  It will be cached either as an activity
16433                    // or empty depending on whether the activity is finishing.  We do
16434                    // this so that we can treat the process as cached for purposes of
16435                    // memory trimming (determing current memory level, trim command to
16436                    // send to process) since there can be an arbitrary number of stopping
16437                    // processes and they should soon all go into the cached state.
16438                    if (!r.finishing) {
16439                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16440                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16441                        }
16442                    }
16443                    app.cached = false;
16444                    app.empty = false;
16445                    foregroundActivities = true;
16446                } else {
16447                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16448                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16449                        app.adjType = "cch-act";
16450                    }
16451                }
16452            }
16453        }
16454
16455        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16456            if (app.foregroundServices) {
16457                // The user is aware of this app, so make it visible.
16458                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16459                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16460                app.cached = false;
16461                app.adjType = "fg-service";
16462                schedGroup = Process.THREAD_GROUP_DEFAULT;
16463            } else if (app.forcingToForeground != null) {
16464                // The user is aware of this app, so make it visible.
16465                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16466                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16467                app.cached = false;
16468                app.adjType = "force-fg";
16469                app.adjSource = app.forcingToForeground;
16470                schedGroup = Process.THREAD_GROUP_DEFAULT;
16471            }
16472        }
16473
16474        if (app == mHeavyWeightProcess) {
16475            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16476                // We don't want to kill the current heavy-weight process.
16477                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16478                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16479                app.cached = false;
16480                app.adjType = "heavy";
16481            }
16482            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16483                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16484            }
16485        }
16486
16487        if (app == mHomeProcess) {
16488            if (adj > ProcessList.HOME_APP_ADJ) {
16489                // This process is hosting what we currently consider to be the
16490                // home app, so we don't want to let it go into the background.
16491                adj = ProcessList.HOME_APP_ADJ;
16492                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16493                app.cached = false;
16494                app.adjType = "home";
16495            }
16496            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16497                procState = ActivityManager.PROCESS_STATE_HOME;
16498            }
16499        }
16500
16501        if (app == mPreviousProcess && app.activities.size() > 0) {
16502            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16503                // This was the previous process that showed UI to the user.
16504                // We want to try to keep it around more aggressively, to give
16505                // a good experience around switching between two apps.
16506                adj = ProcessList.PREVIOUS_APP_ADJ;
16507                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16508                app.cached = false;
16509                app.adjType = "previous";
16510            }
16511            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16512                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16513            }
16514        }
16515
16516        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16517                + " reason=" + app.adjType);
16518
16519        // By default, we use the computed adjustment.  It may be changed if
16520        // there are applications dependent on our services or providers, but
16521        // this gives us a baseline and makes sure we don't get into an
16522        // infinite recursion.
16523        app.adjSeq = mAdjSeq;
16524        app.curRawAdj = adj;
16525        app.hasStartedServices = false;
16526
16527        if (mBackupTarget != null && app == mBackupTarget.app) {
16528            // If possible we want to avoid killing apps while they're being backed up
16529            if (adj > ProcessList.BACKUP_APP_ADJ) {
16530                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16531                adj = ProcessList.BACKUP_APP_ADJ;
16532                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16533                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16534                }
16535                app.adjType = "backup";
16536                app.cached = false;
16537            }
16538            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16539                procState = ActivityManager.PROCESS_STATE_BACKUP;
16540            }
16541        }
16542
16543        boolean mayBeTop = false;
16544
16545        for (int is = app.services.size()-1;
16546                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16547                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16548                        || procState > ActivityManager.PROCESS_STATE_TOP);
16549                is--) {
16550            ServiceRecord s = app.services.valueAt(is);
16551            if (s.startRequested) {
16552                app.hasStartedServices = true;
16553                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16554                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16555                }
16556                if (app.hasShownUi && app != mHomeProcess) {
16557                    // If this process has shown some UI, let it immediately
16558                    // go to the LRU list because it may be pretty heavy with
16559                    // UI stuff.  We'll tag it with a label just to help
16560                    // debug and understand what is going on.
16561                    if (adj > ProcessList.SERVICE_ADJ) {
16562                        app.adjType = "cch-started-ui-services";
16563                    }
16564                } else {
16565                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16566                        // This service has seen some activity within
16567                        // recent memory, so we will keep its process ahead
16568                        // of the background processes.
16569                        if (adj > ProcessList.SERVICE_ADJ) {
16570                            adj = ProcessList.SERVICE_ADJ;
16571                            app.adjType = "started-services";
16572                            app.cached = false;
16573                        }
16574                    }
16575                    // If we have let the service slide into the background
16576                    // state, still have some text describing what it is doing
16577                    // even though the service no longer has an impact.
16578                    if (adj > ProcessList.SERVICE_ADJ) {
16579                        app.adjType = "cch-started-services";
16580                    }
16581                }
16582            }
16583            for (int conni = s.connections.size()-1;
16584                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16585                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16586                            || procState > ActivityManager.PROCESS_STATE_TOP);
16587                    conni--) {
16588                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16589                for (int i = 0;
16590                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16591                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16592                                || procState > ActivityManager.PROCESS_STATE_TOP);
16593                        i++) {
16594                    // XXX should compute this based on the max of
16595                    // all connected clients.
16596                    ConnectionRecord cr = clist.get(i);
16597                    if (cr.binding.client == app) {
16598                        // Binding to ourself is not interesting.
16599                        continue;
16600                    }
16601                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16602                        ProcessRecord client = cr.binding.client;
16603                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16604                                TOP_APP, doingAll, now);
16605                        int clientProcState = client.curProcState;
16606                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16607                            // If the other app is cached for any reason, for purposes here
16608                            // we are going to consider it empty.  The specific cached state
16609                            // doesn't propagate except under certain conditions.
16610                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16611                        }
16612                        String adjType = null;
16613                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16614                            // Not doing bind OOM management, so treat
16615                            // this guy more like a started service.
16616                            if (app.hasShownUi && app != mHomeProcess) {
16617                                // If this process has shown some UI, let it immediately
16618                                // go to the LRU list because it may be pretty heavy with
16619                                // UI stuff.  We'll tag it with a label just to help
16620                                // debug and understand what is going on.
16621                                if (adj > clientAdj) {
16622                                    adjType = "cch-bound-ui-services";
16623                                }
16624                                app.cached = false;
16625                                clientAdj = adj;
16626                                clientProcState = procState;
16627                            } else {
16628                                if (now >= (s.lastActivity
16629                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16630                                    // This service has not seen activity within
16631                                    // recent memory, so allow it to drop to the
16632                                    // LRU list if there is no other reason to keep
16633                                    // it around.  We'll also tag it with a label just
16634                                    // to help debug and undertand what is going on.
16635                                    if (adj > clientAdj) {
16636                                        adjType = "cch-bound-services";
16637                                    }
16638                                    clientAdj = adj;
16639                                }
16640                            }
16641                        }
16642                        if (adj > clientAdj) {
16643                            // If this process has recently shown UI, and
16644                            // the process that is binding to it is less
16645                            // important than being visible, then we don't
16646                            // care about the binding as much as we care
16647                            // about letting this process get into the LRU
16648                            // list to be killed and restarted if needed for
16649                            // memory.
16650                            if (app.hasShownUi && app != mHomeProcess
16651                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16652                                adjType = "cch-bound-ui-services";
16653                            } else {
16654                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16655                                        |Context.BIND_IMPORTANT)) != 0) {
16656                                    adj = clientAdj;
16657                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16658                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16659                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16660                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16661                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16662                                    adj = clientAdj;
16663                                } else {
16664                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16665                                        adj = ProcessList.VISIBLE_APP_ADJ;
16666                                    }
16667                                }
16668                                if (!client.cached) {
16669                                    app.cached = false;
16670                                }
16671                                adjType = "service";
16672                            }
16673                        }
16674                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16675                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16676                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16677                            }
16678                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16679                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16680                                    // Special handling of clients who are in the top state.
16681                                    // We *may* want to consider this process to be in the
16682                                    // top state as well, but only if there is not another
16683                                    // reason for it to be running.  Being on the top is a
16684                                    // special state, meaning you are specifically running
16685                                    // for the current top app.  If the process is already
16686                                    // running in the background for some other reason, it
16687                                    // is more important to continue considering it to be
16688                                    // in the background state.
16689                                    mayBeTop = true;
16690                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16691                                } else {
16692                                    // Special handling for above-top states (persistent
16693                                    // processes).  These should not bring the current process
16694                                    // into the top state, since they are not on top.  Instead
16695                                    // give them the best state after that.
16696                                    clientProcState =
16697                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16698                                }
16699                            }
16700                        } else {
16701                            if (clientProcState <
16702                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16703                                clientProcState =
16704                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16705                            }
16706                        }
16707                        if (procState > clientProcState) {
16708                            procState = clientProcState;
16709                        }
16710                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16711                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16712                            app.pendingUiClean = true;
16713                        }
16714                        if (adjType != null) {
16715                            app.adjType = adjType;
16716                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16717                                    .REASON_SERVICE_IN_USE;
16718                            app.adjSource = cr.binding.client;
16719                            app.adjSourceProcState = clientProcState;
16720                            app.adjTarget = s.name;
16721                        }
16722                    }
16723                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16724                        app.treatLikeActivity = true;
16725                    }
16726                    final ActivityRecord a = cr.activity;
16727                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16728                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16729                                (a.visible || a.state == ActivityState.RESUMED
16730                                 || a.state == ActivityState.PAUSING)) {
16731                            adj = ProcessList.FOREGROUND_APP_ADJ;
16732                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16733                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16734                            }
16735                            app.cached = false;
16736                            app.adjType = "service";
16737                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16738                                    .REASON_SERVICE_IN_USE;
16739                            app.adjSource = a;
16740                            app.adjSourceProcState = procState;
16741                            app.adjTarget = s.name;
16742                        }
16743                    }
16744                }
16745            }
16746        }
16747
16748        for (int provi = app.pubProviders.size()-1;
16749                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16750                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16751                        || procState > ActivityManager.PROCESS_STATE_TOP);
16752                provi--) {
16753            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16754            for (int i = cpr.connections.size()-1;
16755                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16756                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16757                            || procState > ActivityManager.PROCESS_STATE_TOP);
16758                    i--) {
16759                ContentProviderConnection conn = cpr.connections.get(i);
16760                ProcessRecord client = conn.client;
16761                if (client == app) {
16762                    // Being our own client is not interesting.
16763                    continue;
16764                }
16765                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16766                int clientProcState = client.curProcState;
16767                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16768                    // If the other app is cached for any reason, for purposes here
16769                    // we are going to consider it empty.
16770                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16771                }
16772                if (adj > clientAdj) {
16773                    if (app.hasShownUi && app != mHomeProcess
16774                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16775                        app.adjType = "cch-ui-provider";
16776                    } else {
16777                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16778                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16779                        app.adjType = "provider";
16780                    }
16781                    app.cached &= client.cached;
16782                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16783                            .REASON_PROVIDER_IN_USE;
16784                    app.adjSource = client;
16785                    app.adjSourceProcState = clientProcState;
16786                    app.adjTarget = cpr.name;
16787                }
16788                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16789                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16790                        // Special handling of clients who are in the top state.
16791                        // We *may* want to consider this process to be in the
16792                        // top state as well, but only if there is not another
16793                        // reason for it to be running.  Being on the top is a
16794                        // special state, meaning you are specifically running
16795                        // for the current top app.  If the process is already
16796                        // running in the background for some other reason, it
16797                        // is more important to continue considering it to be
16798                        // in the background state.
16799                        mayBeTop = true;
16800                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16801                    } else {
16802                        // Special handling for above-top states (persistent
16803                        // processes).  These should not bring the current process
16804                        // into the top state, since they are not on top.  Instead
16805                        // give them the best state after that.
16806                        clientProcState =
16807                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16808                    }
16809                }
16810                if (procState > clientProcState) {
16811                    procState = clientProcState;
16812                }
16813                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16814                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16815                }
16816            }
16817            // If the provider has external (non-framework) process
16818            // dependencies, ensure that its adjustment is at least
16819            // FOREGROUND_APP_ADJ.
16820            if (cpr.hasExternalProcessHandles()) {
16821                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16822                    adj = ProcessList.FOREGROUND_APP_ADJ;
16823                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16824                    app.cached = false;
16825                    app.adjType = "provider";
16826                    app.adjTarget = cpr.name;
16827                }
16828                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16829                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16830                }
16831            }
16832        }
16833
16834        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16835            // A client of one of our services or providers is in the top state.  We
16836            // *may* want to be in the top state, but not if we are already running in
16837            // the background for some other reason.  For the decision here, we are going
16838            // to pick out a few specific states that we want to remain in when a client
16839            // is top (states that tend to be longer-term) and otherwise allow it to go
16840            // to the top state.
16841            switch (procState) {
16842                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16843                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16844                case ActivityManager.PROCESS_STATE_SERVICE:
16845                    // These all are longer-term states, so pull them up to the top
16846                    // of the background states, but not all the way to the top state.
16847                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16848                    break;
16849                default:
16850                    // Otherwise, top is a better choice, so take it.
16851                    procState = ActivityManager.PROCESS_STATE_TOP;
16852                    break;
16853            }
16854        }
16855
16856        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16857            if (app.hasClientActivities) {
16858                // This is a cached process, but with client activities.  Mark it so.
16859                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16860                app.adjType = "cch-client-act";
16861            } else if (app.treatLikeActivity) {
16862                // This is a cached process, but somebody wants us to treat it like it has
16863                // an activity, okay!
16864                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16865                app.adjType = "cch-as-act";
16866            }
16867        }
16868
16869        if (adj == ProcessList.SERVICE_ADJ) {
16870            if (doingAll) {
16871                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16872                mNewNumServiceProcs++;
16873                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16874                if (!app.serviceb) {
16875                    // This service isn't far enough down on the LRU list to
16876                    // normally be a B service, but if we are low on RAM and it
16877                    // is large we want to force it down since we would prefer to
16878                    // keep launcher over it.
16879                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16880                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16881                        app.serviceHighRam = true;
16882                        app.serviceb = true;
16883                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16884                    } else {
16885                        mNewNumAServiceProcs++;
16886                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16887                    }
16888                } else {
16889                    app.serviceHighRam = false;
16890                }
16891            }
16892            if (app.serviceb) {
16893                adj = ProcessList.SERVICE_B_ADJ;
16894            }
16895        }
16896
16897        app.curRawAdj = adj;
16898
16899        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16900        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16901        if (adj > app.maxAdj) {
16902            adj = app.maxAdj;
16903            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16904                schedGroup = Process.THREAD_GROUP_DEFAULT;
16905            }
16906        }
16907
16908        // Do final modification to adj.  Everything we do between here and applying
16909        // the final setAdj must be done in this function, because we will also use
16910        // it when computing the final cached adj later.  Note that we don't need to
16911        // worry about this for max adj above, since max adj will always be used to
16912        // keep it out of the cached vaues.
16913        app.curAdj = app.modifyRawOomAdj(adj);
16914        app.curSchedGroup = schedGroup;
16915        app.curProcState = procState;
16916        app.foregroundActivities = foregroundActivities;
16917
16918        return app.curRawAdj;
16919    }
16920
16921    /**
16922     * Schedule PSS collection of a process.
16923     */
16924    void requestPssLocked(ProcessRecord proc, int procState) {
16925        if (mPendingPssProcesses.contains(proc)) {
16926            return;
16927        }
16928        if (mPendingPssProcesses.size() == 0) {
16929            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16930        }
16931        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16932        proc.pssProcState = procState;
16933        mPendingPssProcesses.add(proc);
16934    }
16935
16936    /**
16937     * Schedule PSS collection of all processes.
16938     */
16939    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16940        if (!always) {
16941            if (now < (mLastFullPssTime +
16942                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16943                return;
16944            }
16945        }
16946        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16947        mLastFullPssTime = now;
16948        mFullPssPending = true;
16949        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16950        mPendingPssProcesses.clear();
16951        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16952            ProcessRecord app = mLruProcesses.get(i);
16953            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16954                app.pssProcState = app.setProcState;
16955                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16956                        isSleeping(), now);
16957                mPendingPssProcesses.add(app);
16958            }
16959        }
16960        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16961    }
16962
16963    /**
16964     * Ask a given process to GC right now.
16965     */
16966    final void performAppGcLocked(ProcessRecord app) {
16967        try {
16968            app.lastRequestedGc = SystemClock.uptimeMillis();
16969            if (app.thread != null) {
16970                if (app.reportLowMemory) {
16971                    app.reportLowMemory = false;
16972                    app.thread.scheduleLowMemory();
16973                } else {
16974                    app.thread.processInBackground();
16975                }
16976            }
16977        } catch (Exception e) {
16978            // whatever.
16979        }
16980    }
16981
16982    /**
16983     * Returns true if things are idle enough to perform GCs.
16984     */
16985    private final boolean canGcNowLocked() {
16986        boolean processingBroadcasts = false;
16987        for (BroadcastQueue q : mBroadcastQueues) {
16988            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16989                processingBroadcasts = true;
16990            }
16991        }
16992        return !processingBroadcasts
16993                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16994    }
16995
16996    /**
16997     * Perform GCs on all processes that are waiting for it, but only
16998     * if things are idle.
16999     */
17000    final void performAppGcsLocked() {
17001        final int N = mProcessesToGc.size();
17002        if (N <= 0) {
17003            return;
17004        }
17005        if (canGcNowLocked()) {
17006            while (mProcessesToGc.size() > 0) {
17007                ProcessRecord proc = mProcessesToGc.remove(0);
17008                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17009                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17010                            <= SystemClock.uptimeMillis()) {
17011                        // To avoid spamming the system, we will GC processes one
17012                        // at a time, waiting a few seconds between each.
17013                        performAppGcLocked(proc);
17014                        scheduleAppGcsLocked();
17015                        return;
17016                    } else {
17017                        // It hasn't been long enough since we last GCed this
17018                        // process...  put it in the list to wait for its time.
17019                        addProcessToGcListLocked(proc);
17020                        break;
17021                    }
17022                }
17023            }
17024
17025            scheduleAppGcsLocked();
17026        }
17027    }
17028
17029    /**
17030     * If all looks good, perform GCs on all processes waiting for them.
17031     */
17032    final void performAppGcsIfAppropriateLocked() {
17033        if (canGcNowLocked()) {
17034            performAppGcsLocked();
17035            return;
17036        }
17037        // Still not idle, wait some more.
17038        scheduleAppGcsLocked();
17039    }
17040
17041    /**
17042     * Schedule the execution of all pending app GCs.
17043     */
17044    final void scheduleAppGcsLocked() {
17045        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17046
17047        if (mProcessesToGc.size() > 0) {
17048            // Schedule a GC for the time to the next process.
17049            ProcessRecord proc = mProcessesToGc.get(0);
17050            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17051
17052            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17053            long now = SystemClock.uptimeMillis();
17054            if (when < (now+GC_TIMEOUT)) {
17055                when = now + GC_TIMEOUT;
17056            }
17057            mHandler.sendMessageAtTime(msg, when);
17058        }
17059    }
17060
17061    /**
17062     * Add a process to the array of processes waiting to be GCed.  Keeps the
17063     * list in sorted order by the last GC time.  The process can't already be
17064     * on the list.
17065     */
17066    final void addProcessToGcListLocked(ProcessRecord proc) {
17067        boolean added = false;
17068        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17069            if (mProcessesToGc.get(i).lastRequestedGc <
17070                    proc.lastRequestedGc) {
17071                added = true;
17072                mProcessesToGc.add(i+1, proc);
17073                break;
17074            }
17075        }
17076        if (!added) {
17077            mProcessesToGc.add(0, proc);
17078        }
17079    }
17080
17081    /**
17082     * Set up to ask a process to GC itself.  This will either do it
17083     * immediately, or put it on the list of processes to gc the next
17084     * time things are idle.
17085     */
17086    final void scheduleAppGcLocked(ProcessRecord app) {
17087        long now = SystemClock.uptimeMillis();
17088        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17089            return;
17090        }
17091        if (!mProcessesToGc.contains(app)) {
17092            addProcessToGcListLocked(app);
17093            scheduleAppGcsLocked();
17094        }
17095    }
17096
17097    final void checkExcessivePowerUsageLocked(boolean doKills) {
17098        updateCpuStatsNow();
17099
17100        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17101        boolean doWakeKills = doKills;
17102        boolean doCpuKills = doKills;
17103        if (mLastPowerCheckRealtime == 0) {
17104            doWakeKills = false;
17105        }
17106        if (mLastPowerCheckUptime == 0) {
17107            doCpuKills = false;
17108        }
17109        if (stats.isScreenOn()) {
17110            doWakeKills = false;
17111        }
17112        final long curRealtime = SystemClock.elapsedRealtime();
17113        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17114        final long curUptime = SystemClock.uptimeMillis();
17115        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17116        mLastPowerCheckRealtime = curRealtime;
17117        mLastPowerCheckUptime = curUptime;
17118        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17119            doWakeKills = false;
17120        }
17121        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17122            doCpuKills = false;
17123        }
17124        int i = mLruProcesses.size();
17125        while (i > 0) {
17126            i--;
17127            ProcessRecord app = mLruProcesses.get(i);
17128            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17129                long wtime;
17130                synchronized (stats) {
17131                    wtime = stats.getProcessWakeTime(app.info.uid,
17132                            app.pid, curRealtime);
17133                }
17134                long wtimeUsed = wtime - app.lastWakeTime;
17135                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17136                if (DEBUG_POWER) {
17137                    StringBuilder sb = new StringBuilder(128);
17138                    sb.append("Wake for ");
17139                    app.toShortString(sb);
17140                    sb.append(": over ");
17141                    TimeUtils.formatDuration(realtimeSince, sb);
17142                    sb.append(" used ");
17143                    TimeUtils.formatDuration(wtimeUsed, sb);
17144                    sb.append(" (");
17145                    sb.append((wtimeUsed*100)/realtimeSince);
17146                    sb.append("%)");
17147                    Slog.i(TAG, sb.toString());
17148                    sb.setLength(0);
17149                    sb.append("CPU for ");
17150                    app.toShortString(sb);
17151                    sb.append(": over ");
17152                    TimeUtils.formatDuration(uptimeSince, sb);
17153                    sb.append(" used ");
17154                    TimeUtils.formatDuration(cputimeUsed, sb);
17155                    sb.append(" (");
17156                    sb.append((cputimeUsed*100)/uptimeSince);
17157                    sb.append("%)");
17158                    Slog.i(TAG, sb.toString());
17159                }
17160                // If a process has held a wake lock for more
17161                // than 50% of the time during this period,
17162                // that sounds bad.  Kill!
17163                if (doWakeKills && realtimeSince > 0
17164                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17165                    synchronized (stats) {
17166                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17167                                realtimeSince, wtimeUsed);
17168                    }
17169                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17170                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17171                } else if (doCpuKills && uptimeSince > 0
17172                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17173                    synchronized (stats) {
17174                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17175                                uptimeSince, cputimeUsed);
17176                    }
17177                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17178                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17179                } else {
17180                    app.lastWakeTime = wtime;
17181                    app.lastCpuTime = app.curCpuTime;
17182                }
17183            }
17184        }
17185    }
17186
17187    private final boolean applyOomAdjLocked(ProcessRecord app,
17188            ProcessRecord TOP_APP, boolean doingAll, long now) {
17189        boolean success = true;
17190
17191        if (app.curRawAdj != app.setRawAdj) {
17192            app.setRawAdj = app.curRawAdj;
17193        }
17194
17195        int changes = 0;
17196
17197        if (app.curAdj != app.setAdj) {
17198            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17199            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17200                TAG, "Set " + app.pid + " " + app.processName +
17201                " adj " + app.curAdj + ": " + app.adjType);
17202            app.setAdj = app.curAdj;
17203        }
17204
17205        if (app.setSchedGroup != app.curSchedGroup) {
17206            app.setSchedGroup = app.curSchedGroup;
17207            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17208                    "Setting process group of " + app.processName
17209                    + " to " + app.curSchedGroup);
17210            if (app.waitingToKill != null &&
17211                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17212                app.kill(app.waitingToKill, true);
17213                success = false;
17214            } else {
17215                if (true) {
17216                    long oldId = Binder.clearCallingIdentity();
17217                    try {
17218                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17219                    } catch (Exception e) {
17220                        Slog.w(TAG, "Failed setting process group of " + app.pid
17221                                + " to " + app.curSchedGroup);
17222                        e.printStackTrace();
17223                    } finally {
17224                        Binder.restoreCallingIdentity(oldId);
17225                    }
17226                } else {
17227                    if (app.thread != null) {
17228                        try {
17229                            app.thread.setSchedulingGroup(app.curSchedGroup);
17230                        } catch (RemoteException e) {
17231                        }
17232                    }
17233                }
17234                Process.setSwappiness(app.pid,
17235                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17236            }
17237        }
17238        if (app.repForegroundActivities != app.foregroundActivities) {
17239            app.repForegroundActivities = app.foregroundActivities;
17240            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17241        }
17242        if (app.repProcState != app.curProcState) {
17243            app.repProcState = app.curProcState;
17244            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17245            if (app.thread != null) {
17246                try {
17247                    if (false) {
17248                        //RuntimeException h = new RuntimeException("here");
17249                        Slog.i(TAG, "Sending new process state " + app.repProcState
17250                                + " to " + app /*, h*/);
17251                    }
17252                    app.thread.setProcessState(app.repProcState);
17253                } catch (RemoteException e) {
17254                }
17255            }
17256        }
17257        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17258                app.setProcState)) {
17259            app.lastStateTime = now;
17260            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17261                    isSleeping(), now);
17262            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17263                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17264                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17265                    + (app.nextPssTime-now) + ": " + app);
17266        } else {
17267            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17268                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17269                requestPssLocked(app, app.setProcState);
17270                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17271                        isSleeping(), now);
17272            } else if (false && DEBUG_PSS) {
17273                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17274            }
17275        }
17276        if (app.setProcState != app.curProcState) {
17277            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17278                    "Proc state change of " + app.processName
17279                    + " to " + app.curProcState);
17280            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17281            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17282            if (setImportant && !curImportant) {
17283                // This app is no longer something we consider important enough to allow to
17284                // use arbitrary amounts of battery power.  Note
17285                // its current wake lock time to later know to kill it if
17286                // it is not behaving well.
17287                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17288                synchronized (stats) {
17289                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17290                            app.pid, SystemClock.elapsedRealtime());
17291                }
17292                app.lastCpuTime = app.curCpuTime;
17293
17294            }
17295            app.setProcState = app.curProcState;
17296            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17297                app.notCachedSinceIdle = false;
17298            }
17299            if (!doingAll) {
17300                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17301            } else {
17302                app.procStateChanged = true;
17303            }
17304        }
17305
17306        if (changes != 0) {
17307            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17308            int i = mPendingProcessChanges.size()-1;
17309            ProcessChangeItem item = null;
17310            while (i >= 0) {
17311                item = mPendingProcessChanges.get(i);
17312                if (item.pid == app.pid) {
17313                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17314                    break;
17315                }
17316                i--;
17317            }
17318            if (i < 0) {
17319                // No existing item in pending changes; need a new one.
17320                final int NA = mAvailProcessChanges.size();
17321                if (NA > 0) {
17322                    item = mAvailProcessChanges.remove(NA-1);
17323                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17324                } else {
17325                    item = new ProcessChangeItem();
17326                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17327                }
17328                item.changes = 0;
17329                item.pid = app.pid;
17330                item.uid = app.info.uid;
17331                if (mPendingProcessChanges.size() == 0) {
17332                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17333                            "*** Enqueueing dispatch processes changed!");
17334                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17335                }
17336                mPendingProcessChanges.add(item);
17337            }
17338            item.changes |= changes;
17339            item.processState = app.repProcState;
17340            item.foregroundActivities = app.repForegroundActivities;
17341            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17342                    + Integer.toHexString(System.identityHashCode(item))
17343                    + " " + app.toShortString() + ": changes=" + item.changes
17344                    + " procState=" + item.processState
17345                    + " foreground=" + item.foregroundActivities
17346                    + " type=" + app.adjType + " source=" + app.adjSource
17347                    + " target=" + app.adjTarget);
17348        }
17349
17350        return success;
17351    }
17352
17353    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17354        if (proc.thread != null) {
17355            if (proc.baseProcessTracker != null) {
17356                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17357            }
17358            if (proc.repProcState >= 0) {
17359                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17360                        proc.repProcState);
17361            }
17362        }
17363    }
17364
17365    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17366            ProcessRecord TOP_APP, boolean doingAll, long now) {
17367        if (app.thread == null) {
17368            return false;
17369        }
17370
17371        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17372
17373        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17374    }
17375
17376    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17377            boolean oomAdj) {
17378        if (isForeground != proc.foregroundServices) {
17379            proc.foregroundServices = isForeground;
17380            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17381                    proc.info.uid);
17382            if (isForeground) {
17383                if (curProcs == null) {
17384                    curProcs = new ArrayList<ProcessRecord>();
17385                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17386                }
17387                if (!curProcs.contains(proc)) {
17388                    curProcs.add(proc);
17389                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17390                            proc.info.packageName, proc.info.uid);
17391                }
17392            } else {
17393                if (curProcs != null) {
17394                    if (curProcs.remove(proc)) {
17395                        mBatteryStatsService.noteEvent(
17396                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17397                                proc.info.packageName, proc.info.uid);
17398                        if (curProcs.size() <= 0) {
17399                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17400                        }
17401                    }
17402                }
17403            }
17404            if (oomAdj) {
17405                updateOomAdjLocked();
17406            }
17407        }
17408    }
17409
17410    private final ActivityRecord resumedAppLocked() {
17411        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17412        String pkg;
17413        int uid;
17414        if (act != null) {
17415            pkg = act.packageName;
17416            uid = act.info.applicationInfo.uid;
17417        } else {
17418            pkg = null;
17419            uid = -1;
17420        }
17421        // Has the UID or resumed package name changed?
17422        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17423                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17424            if (mCurResumedPackage != null) {
17425                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17426                        mCurResumedPackage, mCurResumedUid);
17427            }
17428            mCurResumedPackage = pkg;
17429            mCurResumedUid = uid;
17430            if (mCurResumedPackage != null) {
17431                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17432                        mCurResumedPackage, mCurResumedUid);
17433            }
17434        }
17435        return act;
17436    }
17437
17438    final boolean updateOomAdjLocked(ProcessRecord app) {
17439        final ActivityRecord TOP_ACT = resumedAppLocked();
17440        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17441        final boolean wasCached = app.cached;
17442
17443        mAdjSeq++;
17444
17445        // This is the desired cached adjusment we want to tell it to use.
17446        // If our app is currently cached, we know it, and that is it.  Otherwise,
17447        // we don't know it yet, and it needs to now be cached we will then
17448        // need to do a complete oom adj.
17449        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17450                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17451        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17452                SystemClock.uptimeMillis());
17453        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17454            // Changed to/from cached state, so apps after it in the LRU
17455            // list may also be changed.
17456            updateOomAdjLocked();
17457        }
17458        return success;
17459    }
17460
17461    final void updateOomAdjLocked() {
17462        final ActivityRecord TOP_ACT = resumedAppLocked();
17463        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17464        final long now = SystemClock.uptimeMillis();
17465        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17466        final int N = mLruProcesses.size();
17467
17468        if (false) {
17469            RuntimeException e = new RuntimeException();
17470            e.fillInStackTrace();
17471            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17472        }
17473
17474        mAdjSeq++;
17475        mNewNumServiceProcs = 0;
17476        mNewNumAServiceProcs = 0;
17477
17478        final int emptyProcessLimit;
17479        final int cachedProcessLimit;
17480        if (mProcessLimit <= 0) {
17481            emptyProcessLimit = cachedProcessLimit = 0;
17482        } else if (mProcessLimit == 1) {
17483            emptyProcessLimit = 1;
17484            cachedProcessLimit = 0;
17485        } else {
17486            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17487            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17488        }
17489
17490        // Let's determine how many processes we have running vs.
17491        // how many slots we have for background processes; we may want
17492        // to put multiple processes in a slot of there are enough of
17493        // them.
17494        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17495                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17496        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17497        if (numEmptyProcs > cachedProcessLimit) {
17498            // If there are more empty processes than our limit on cached
17499            // processes, then use the cached process limit for the factor.
17500            // This ensures that the really old empty processes get pushed
17501            // down to the bottom, so if we are running low on memory we will
17502            // have a better chance at keeping around more cached processes
17503            // instead of a gazillion empty processes.
17504            numEmptyProcs = cachedProcessLimit;
17505        }
17506        int emptyFactor = numEmptyProcs/numSlots;
17507        if (emptyFactor < 1) emptyFactor = 1;
17508        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17509        if (cachedFactor < 1) cachedFactor = 1;
17510        int stepCached = 0;
17511        int stepEmpty = 0;
17512        int numCached = 0;
17513        int numEmpty = 0;
17514        int numTrimming = 0;
17515
17516        mNumNonCachedProcs = 0;
17517        mNumCachedHiddenProcs = 0;
17518
17519        // First update the OOM adjustment for each of the
17520        // application processes based on their current state.
17521        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17522        int nextCachedAdj = curCachedAdj+1;
17523        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17524        int nextEmptyAdj = curEmptyAdj+2;
17525        for (int i=N-1; i>=0; i--) {
17526            ProcessRecord app = mLruProcesses.get(i);
17527            if (!app.killedByAm && app.thread != null) {
17528                app.procStateChanged = false;
17529                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17530
17531                // If we haven't yet assigned the final cached adj
17532                // to the process, do that now.
17533                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17534                    switch (app.curProcState) {
17535                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17536                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17537                            // This process is a cached process holding activities...
17538                            // assign it the next cached value for that type, and then
17539                            // step that cached level.
17540                            app.curRawAdj = curCachedAdj;
17541                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17542                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17543                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17544                                    + ")");
17545                            if (curCachedAdj != nextCachedAdj) {
17546                                stepCached++;
17547                                if (stepCached >= cachedFactor) {
17548                                    stepCached = 0;
17549                                    curCachedAdj = nextCachedAdj;
17550                                    nextCachedAdj += 2;
17551                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17552                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17553                                    }
17554                                }
17555                            }
17556                            break;
17557                        default:
17558                            // For everything else, assign next empty cached process
17559                            // level and bump that up.  Note that this means that
17560                            // long-running services that have dropped down to the
17561                            // cached level will be treated as empty (since their process
17562                            // state is still as a service), which is what we want.
17563                            app.curRawAdj = curEmptyAdj;
17564                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17565                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17566                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17567                                    + ")");
17568                            if (curEmptyAdj != nextEmptyAdj) {
17569                                stepEmpty++;
17570                                if (stepEmpty >= emptyFactor) {
17571                                    stepEmpty = 0;
17572                                    curEmptyAdj = nextEmptyAdj;
17573                                    nextEmptyAdj += 2;
17574                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17575                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17576                                    }
17577                                }
17578                            }
17579                            break;
17580                    }
17581                }
17582
17583                applyOomAdjLocked(app, TOP_APP, true, now);
17584
17585                // Count the number of process types.
17586                switch (app.curProcState) {
17587                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17588                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17589                        mNumCachedHiddenProcs++;
17590                        numCached++;
17591                        if (numCached > cachedProcessLimit) {
17592                            app.kill("cached #" + numCached, true);
17593                        }
17594                        break;
17595                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17596                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17597                                && app.lastActivityTime < oldTime) {
17598                            app.kill("empty for "
17599                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17600                                    / 1000) + "s", true);
17601                        } else {
17602                            numEmpty++;
17603                            if (numEmpty > emptyProcessLimit) {
17604                                app.kill("empty #" + numEmpty, true);
17605                            }
17606                        }
17607                        break;
17608                    default:
17609                        mNumNonCachedProcs++;
17610                        break;
17611                }
17612
17613                if (app.isolated && app.services.size() <= 0) {
17614                    // If this is an isolated process, and there are no
17615                    // services running in it, then the process is no longer
17616                    // needed.  We agressively kill these because we can by
17617                    // definition not re-use the same process again, and it is
17618                    // good to avoid having whatever code was running in them
17619                    // left sitting around after no longer needed.
17620                    app.kill("isolated not needed", true);
17621                }
17622
17623                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17624                        && !app.killedByAm) {
17625                    numTrimming++;
17626                }
17627            }
17628        }
17629
17630        mNumServiceProcs = mNewNumServiceProcs;
17631
17632        // Now determine the memory trimming level of background processes.
17633        // Unfortunately we need to start at the back of the list to do this
17634        // properly.  We only do this if the number of background apps we
17635        // are managing to keep around is less than half the maximum we desire;
17636        // if we are keeping a good number around, we'll let them use whatever
17637        // memory they want.
17638        final int numCachedAndEmpty = numCached + numEmpty;
17639        int memFactor;
17640        if (numCached <= ProcessList.TRIM_CACHED_APPS
17641                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17642            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17643                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17644            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17645                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17646            } else {
17647                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17648            }
17649        } else {
17650            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17651        }
17652        // We always allow the memory level to go up (better).  We only allow it to go
17653        // down if we are in a state where that is allowed, *and* the total number of processes
17654        // has gone down since last time.
17655        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17656                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17657                + " last=" + mLastNumProcesses);
17658        if (memFactor > mLastMemoryLevel) {
17659            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17660                memFactor = mLastMemoryLevel;
17661                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17662            }
17663        }
17664        mLastMemoryLevel = memFactor;
17665        mLastNumProcesses = mLruProcesses.size();
17666        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17667        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17668        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17669            if (mLowRamStartTime == 0) {
17670                mLowRamStartTime = now;
17671            }
17672            int step = 0;
17673            int fgTrimLevel;
17674            switch (memFactor) {
17675                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17676                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17677                    break;
17678                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17679                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17680                    break;
17681                default:
17682                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17683                    break;
17684            }
17685            int factor = numTrimming/3;
17686            int minFactor = 2;
17687            if (mHomeProcess != null) minFactor++;
17688            if (mPreviousProcess != null) minFactor++;
17689            if (factor < minFactor) factor = minFactor;
17690            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17691            for (int i=N-1; i>=0; i--) {
17692                ProcessRecord app = mLruProcesses.get(i);
17693                if (allChanged || app.procStateChanged) {
17694                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17695                    app.procStateChanged = false;
17696                }
17697                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17698                        && !app.killedByAm) {
17699                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17700                        try {
17701                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17702                                    "Trimming memory of " + app.processName
17703                                    + " to " + curLevel);
17704                            app.thread.scheduleTrimMemory(curLevel);
17705                        } catch (RemoteException e) {
17706                        }
17707                        if (false) {
17708                            // For now we won't do this; our memory trimming seems
17709                            // to be good enough at this point that destroying
17710                            // activities causes more harm than good.
17711                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17712                                    && app != mHomeProcess && app != mPreviousProcess) {
17713                                // Need to do this on its own message because the stack may not
17714                                // be in a consistent state at this point.
17715                                // For these apps we will also finish their activities
17716                                // to help them free memory.
17717                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17718                            }
17719                        }
17720                    }
17721                    app.trimMemoryLevel = curLevel;
17722                    step++;
17723                    if (step >= factor) {
17724                        step = 0;
17725                        switch (curLevel) {
17726                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17727                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17728                                break;
17729                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17730                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17731                                break;
17732                        }
17733                    }
17734                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17735                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17736                            && app.thread != null) {
17737                        try {
17738                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17739                                    "Trimming memory of heavy-weight " + app.processName
17740                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17741                            app.thread.scheduleTrimMemory(
17742                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17743                        } catch (RemoteException e) {
17744                        }
17745                    }
17746                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17747                } else {
17748                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17749                            || app.systemNoUi) && app.pendingUiClean) {
17750                        // If this application is now in the background and it
17751                        // had done UI, then give it the special trim level to
17752                        // have it free UI resources.
17753                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17754                        if (app.trimMemoryLevel < level && app.thread != null) {
17755                            try {
17756                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17757                                        "Trimming memory of bg-ui " + app.processName
17758                                        + " to " + level);
17759                                app.thread.scheduleTrimMemory(level);
17760                            } catch (RemoteException e) {
17761                            }
17762                        }
17763                        app.pendingUiClean = false;
17764                    }
17765                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17766                        try {
17767                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17768                                    "Trimming memory of fg " + app.processName
17769                                    + " to " + fgTrimLevel);
17770                            app.thread.scheduleTrimMemory(fgTrimLevel);
17771                        } catch (RemoteException e) {
17772                        }
17773                    }
17774                    app.trimMemoryLevel = fgTrimLevel;
17775                }
17776            }
17777        } else {
17778            if (mLowRamStartTime != 0) {
17779                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17780                mLowRamStartTime = 0;
17781            }
17782            for (int i=N-1; i>=0; i--) {
17783                ProcessRecord app = mLruProcesses.get(i);
17784                if (allChanged || app.procStateChanged) {
17785                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17786                    app.procStateChanged = false;
17787                }
17788                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17789                        || app.systemNoUi) && app.pendingUiClean) {
17790                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17791                            && app.thread != null) {
17792                        try {
17793                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17794                                    "Trimming memory of ui hidden " + app.processName
17795                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17796                            app.thread.scheduleTrimMemory(
17797                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17798                        } catch (RemoteException e) {
17799                        }
17800                    }
17801                    app.pendingUiClean = false;
17802                }
17803                app.trimMemoryLevel = 0;
17804            }
17805        }
17806
17807        if (mAlwaysFinishActivities) {
17808            // Need to do this on its own message because the stack may not
17809            // be in a consistent state at this point.
17810            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17811        }
17812
17813        if (allChanged) {
17814            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17815        }
17816
17817        if (mProcessStats.shouldWriteNowLocked(now)) {
17818            mHandler.post(new Runnable() {
17819                @Override public void run() {
17820                    synchronized (ActivityManagerService.this) {
17821                        mProcessStats.writeStateAsyncLocked();
17822                    }
17823                }
17824            });
17825        }
17826
17827        if (DEBUG_OOM_ADJ) {
17828            if (false) {
17829                RuntimeException here = new RuntimeException("here");
17830                here.fillInStackTrace();
17831                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17832            } else {
17833                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17834            }
17835        }
17836    }
17837
17838    final void trimApplications() {
17839        synchronized (this) {
17840            int i;
17841
17842            // First remove any unused application processes whose package
17843            // has been removed.
17844            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17845                final ProcessRecord app = mRemovedProcesses.get(i);
17846                if (app.activities.size() == 0
17847                        && app.curReceiver == null && app.services.size() == 0) {
17848                    Slog.i(
17849                        TAG, "Exiting empty application process "
17850                        + app.processName + " ("
17851                        + (app.thread != null ? app.thread.asBinder() : null)
17852                        + ")\n");
17853                    if (app.pid > 0 && app.pid != MY_PID) {
17854                        app.kill("empty", false);
17855                    } else {
17856                        try {
17857                            app.thread.scheduleExit();
17858                        } catch (Exception e) {
17859                            // Ignore exceptions.
17860                        }
17861                    }
17862                    cleanUpApplicationRecordLocked(app, false, true, -1);
17863                    mRemovedProcesses.remove(i);
17864
17865                    if (app.persistent) {
17866                        addAppLocked(app.info, false, null /* ABI override */);
17867                    }
17868                }
17869            }
17870
17871            // Now update the oom adj for all processes.
17872            updateOomAdjLocked();
17873        }
17874    }
17875
17876    /** This method sends the specified signal to each of the persistent apps */
17877    public void signalPersistentProcesses(int sig) throws RemoteException {
17878        if (sig != Process.SIGNAL_USR1) {
17879            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17880        }
17881
17882        synchronized (this) {
17883            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17884                    != PackageManager.PERMISSION_GRANTED) {
17885                throw new SecurityException("Requires permission "
17886                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17887            }
17888
17889            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17890                ProcessRecord r = mLruProcesses.get(i);
17891                if (r.thread != null && r.persistent) {
17892                    Process.sendSignal(r.pid, sig);
17893                }
17894            }
17895        }
17896    }
17897
17898    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17899        if (proc == null || proc == mProfileProc) {
17900            proc = mProfileProc;
17901            profileType = mProfileType;
17902            clearProfilerLocked();
17903        }
17904        if (proc == null) {
17905            return;
17906        }
17907        try {
17908            proc.thread.profilerControl(false, null, profileType);
17909        } catch (RemoteException e) {
17910            throw new IllegalStateException("Process disappeared");
17911        }
17912    }
17913
17914    private void clearProfilerLocked() {
17915        if (mProfileFd != null) {
17916            try {
17917                mProfileFd.close();
17918            } catch (IOException e) {
17919            }
17920        }
17921        mProfileApp = null;
17922        mProfileProc = null;
17923        mProfileFile = null;
17924        mProfileType = 0;
17925        mAutoStopProfiler = false;
17926        mSamplingInterval = 0;
17927    }
17928
17929    public boolean profileControl(String process, int userId, boolean start,
17930            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17931
17932        try {
17933            synchronized (this) {
17934                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17935                // its own permission.
17936                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17937                        != PackageManager.PERMISSION_GRANTED) {
17938                    throw new SecurityException("Requires permission "
17939                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17940                }
17941
17942                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17943                    throw new IllegalArgumentException("null profile info or fd");
17944                }
17945
17946                ProcessRecord proc = null;
17947                if (process != null) {
17948                    proc = findProcessLocked(process, userId, "profileControl");
17949                }
17950
17951                if (start && (proc == null || proc.thread == null)) {
17952                    throw new IllegalArgumentException("Unknown process: " + process);
17953                }
17954
17955                if (start) {
17956                    stopProfilerLocked(null, 0);
17957                    setProfileApp(proc.info, proc.processName, profilerInfo);
17958                    mProfileProc = proc;
17959                    mProfileType = profileType;
17960                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17961                    try {
17962                        fd = fd.dup();
17963                    } catch (IOException e) {
17964                        fd = null;
17965                    }
17966                    profilerInfo.profileFd = fd;
17967                    proc.thread.profilerControl(start, profilerInfo, profileType);
17968                    fd = null;
17969                    mProfileFd = null;
17970                } else {
17971                    stopProfilerLocked(proc, profileType);
17972                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17973                        try {
17974                            profilerInfo.profileFd.close();
17975                        } catch (IOException e) {
17976                        }
17977                    }
17978                }
17979
17980                return true;
17981            }
17982        } catch (RemoteException e) {
17983            throw new IllegalStateException("Process disappeared");
17984        } finally {
17985            if (profilerInfo != null && profilerInfo.profileFd != null) {
17986                try {
17987                    profilerInfo.profileFd.close();
17988                } catch (IOException e) {
17989                }
17990            }
17991        }
17992    }
17993
17994    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17995        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17996                userId, true, ALLOW_FULL_ONLY, callName, null);
17997        ProcessRecord proc = null;
17998        try {
17999            int pid = Integer.parseInt(process);
18000            synchronized (mPidsSelfLocked) {
18001                proc = mPidsSelfLocked.get(pid);
18002            }
18003        } catch (NumberFormatException e) {
18004        }
18005
18006        if (proc == null) {
18007            ArrayMap<String, SparseArray<ProcessRecord>> all
18008                    = mProcessNames.getMap();
18009            SparseArray<ProcessRecord> procs = all.get(process);
18010            if (procs != null && procs.size() > 0) {
18011                proc = procs.valueAt(0);
18012                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18013                    for (int i=1; i<procs.size(); i++) {
18014                        ProcessRecord thisProc = procs.valueAt(i);
18015                        if (thisProc.userId == userId) {
18016                            proc = thisProc;
18017                            break;
18018                        }
18019                    }
18020                }
18021            }
18022        }
18023
18024        return proc;
18025    }
18026
18027    public boolean dumpHeap(String process, int userId, boolean managed,
18028            String path, ParcelFileDescriptor fd) throws RemoteException {
18029
18030        try {
18031            synchronized (this) {
18032                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18033                // its own permission (same as profileControl).
18034                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18035                        != PackageManager.PERMISSION_GRANTED) {
18036                    throw new SecurityException("Requires permission "
18037                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18038                }
18039
18040                if (fd == null) {
18041                    throw new IllegalArgumentException("null fd");
18042                }
18043
18044                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18045                if (proc == null || proc.thread == null) {
18046                    throw new IllegalArgumentException("Unknown process: " + process);
18047                }
18048
18049                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18050                if (!isDebuggable) {
18051                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18052                        throw new SecurityException("Process not debuggable: " + proc);
18053                    }
18054                }
18055
18056                proc.thread.dumpHeap(managed, path, fd);
18057                fd = null;
18058                return true;
18059            }
18060        } catch (RemoteException e) {
18061            throw new IllegalStateException("Process disappeared");
18062        } finally {
18063            if (fd != null) {
18064                try {
18065                    fd.close();
18066                } catch (IOException e) {
18067                }
18068            }
18069        }
18070    }
18071
18072    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18073    public void monitor() {
18074        synchronized (this) { }
18075    }
18076
18077    void onCoreSettingsChange(Bundle settings) {
18078        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18079            ProcessRecord processRecord = mLruProcesses.get(i);
18080            try {
18081                if (processRecord.thread != null) {
18082                    processRecord.thread.setCoreSettings(settings);
18083                }
18084            } catch (RemoteException re) {
18085                /* ignore */
18086            }
18087        }
18088    }
18089
18090    // Multi-user methods
18091
18092    /**
18093     * Start user, if its not already running, but don't bring it to foreground.
18094     */
18095    @Override
18096    public boolean startUserInBackground(final int userId) {
18097        return startUser(userId, /* foreground */ false);
18098    }
18099
18100    /**
18101     * Start user, if its not already running, and bring it to foreground.
18102     */
18103    boolean startUserInForeground(final int userId, Dialog dlg) {
18104        boolean result = startUser(userId, /* foreground */ true);
18105        dlg.dismiss();
18106        return result;
18107    }
18108
18109    /**
18110     * Refreshes the list of users related to the current user when either a
18111     * user switch happens or when a new related user is started in the
18112     * background.
18113     */
18114    private void updateCurrentProfileIdsLocked() {
18115        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18116                mCurrentUserId, false /* enabledOnly */);
18117        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18118        for (int i = 0; i < currentProfileIds.length; i++) {
18119            currentProfileIds[i] = profiles.get(i).id;
18120        }
18121        mCurrentProfileIds = currentProfileIds;
18122
18123        synchronized (mUserProfileGroupIdsSelfLocked) {
18124            mUserProfileGroupIdsSelfLocked.clear();
18125            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18126            for (int i = 0; i < users.size(); i++) {
18127                UserInfo user = users.get(i);
18128                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18129                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18130                }
18131            }
18132        }
18133    }
18134
18135    private Set getProfileIdsLocked(int userId) {
18136        Set userIds = new HashSet<Integer>();
18137        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18138                userId, false /* enabledOnly */);
18139        for (UserInfo user : profiles) {
18140            userIds.add(Integer.valueOf(user.id));
18141        }
18142        return userIds;
18143    }
18144
18145    @Override
18146    public boolean switchUser(final int userId) {
18147        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18148        String userName;
18149        synchronized (this) {
18150            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18151            if (userInfo == null) {
18152                Slog.w(TAG, "No user info for user #" + userId);
18153                return false;
18154            }
18155            if (userInfo.isManagedProfile()) {
18156                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18157                return false;
18158            }
18159            userName = userInfo.name;
18160            mTargetUserId = userId;
18161        }
18162        mHandler.removeMessages(START_USER_SWITCH_MSG);
18163        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18164        return true;
18165    }
18166
18167    private void showUserSwitchDialog(int userId, String userName) {
18168        // The dialog will show and then initiate the user switch by calling startUserInForeground
18169        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18170                true /* above system */);
18171        d.show();
18172    }
18173
18174    private boolean startUser(final int userId, final boolean foreground) {
18175        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18176                != PackageManager.PERMISSION_GRANTED) {
18177            String msg = "Permission Denial: switchUser() from pid="
18178                    + Binder.getCallingPid()
18179                    + ", uid=" + Binder.getCallingUid()
18180                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18181            Slog.w(TAG, msg);
18182            throw new SecurityException(msg);
18183        }
18184
18185        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18186
18187        final long ident = Binder.clearCallingIdentity();
18188        try {
18189            synchronized (this) {
18190                final int oldUserId = mCurrentUserId;
18191                if (oldUserId == userId) {
18192                    return true;
18193                }
18194
18195                mStackSupervisor.setLockTaskModeLocked(null, false);
18196
18197                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18198                if (userInfo == null) {
18199                    Slog.w(TAG, "No user info for user #" + userId);
18200                    return false;
18201                }
18202                if (foreground && userInfo.isManagedProfile()) {
18203                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18204                    return false;
18205                }
18206
18207                if (foreground) {
18208                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18209                            R.anim.screen_user_enter);
18210                }
18211
18212                boolean needStart = false;
18213
18214                // If the user we are switching to is not currently started, then
18215                // we need to start it now.
18216                if (mStartedUsers.get(userId) == null) {
18217                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18218                    updateStartedUserArrayLocked();
18219                    needStart = true;
18220                }
18221
18222                final Integer userIdInt = Integer.valueOf(userId);
18223                mUserLru.remove(userIdInt);
18224                mUserLru.add(userIdInt);
18225
18226                if (foreground) {
18227                    mCurrentUserId = userId;
18228                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18229                    updateCurrentProfileIdsLocked();
18230                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18231                    // Once the internal notion of the active user has switched, we lock the device
18232                    // with the option to show the user switcher on the keyguard.
18233                    mWindowManager.lockNow(null);
18234                } else {
18235                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18236                    updateCurrentProfileIdsLocked();
18237                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18238                    mUserLru.remove(currentUserIdInt);
18239                    mUserLru.add(currentUserIdInt);
18240                }
18241
18242                final UserStartedState uss = mStartedUsers.get(userId);
18243
18244                // Make sure user is in the started state.  If it is currently
18245                // stopping, we need to knock that off.
18246                if (uss.mState == UserStartedState.STATE_STOPPING) {
18247                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18248                    // so we can just fairly silently bring the user back from
18249                    // the almost-dead.
18250                    uss.mState = UserStartedState.STATE_RUNNING;
18251                    updateStartedUserArrayLocked();
18252                    needStart = true;
18253                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18254                    // This means ACTION_SHUTDOWN has been sent, so we will
18255                    // need to treat this as a new boot of the user.
18256                    uss.mState = UserStartedState.STATE_BOOTING;
18257                    updateStartedUserArrayLocked();
18258                    needStart = true;
18259                }
18260
18261                if (uss.mState == UserStartedState.STATE_BOOTING) {
18262                    // Booting up a new user, need to tell system services about it.
18263                    // Note that this is on the same handler as scheduling of broadcasts,
18264                    // which is important because it needs to go first.
18265                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18266                }
18267
18268                if (foreground) {
18269                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18270                            oldUserId));
18271                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18272                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18273                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18274                            oldUserId, userId, uss));
18275                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18276                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18277                }
18278
18279                if (needStart) {
18280                    // Send USER_STARTED broadcast
18281                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18282                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18283                            | Intent.FLAG_RECEIVER_FOREGROUND);
18284                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18285                    broadcastIntentLocked(null, null, intent,
18286                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18287                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18288                }
18289
18290                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18291                    if (userId != UserHandle.USER_OWNER) {
18292                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18293                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18294                        broadcastIntentLocked(null, null, intent, null,
18295                                new IIntentReceiver.Stub() {
18296                                    public void performReceive(Intent intent, int resultCode,
18297                                            String data, Bundle extras, boolean ordered,
18298                                            boolean sticky, int sendingUser) {
18299                                        onUserInitialized(uss, foreground, oldUserId, userId);
18300                                    }
18301                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18302                                true, false, MY_PID, Process.SYSTEM_UID,
18303                                userId);
18304                        uss.initializing = true;
18305                    } else {
18306                        getUserManagerLocked().makeInitialized(userInfo.id);
18307                    }
18308                }
18309
18310                if (foreground) {
18311                    if (!uss.initializing) {
18312                        moveUserToForeground(uss, oldUserId, userId);
18313                    }
18314                } else {
18315                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18316                }
18317
18318                if (needStart) {
18319                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18320                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18321                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18322                    broadcastIntentLocked(null, null, intent,
18323                            null, new IIntentReceiver.Stub() {
18324                                @Override
18325                                public void performReceive(Intent intent, int resultCode, String data,
18326                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18327                                        throws RemoteException {
18328                                }
18329                            }, 0, null, null,
18330                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18331                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18332                }
18333            }
18334        } finally {
18335            Binder.restoreCallingIdentity(ident);
18336        }
18337
18338        return true;
18339    }
18340
18341    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18342        long ident = Binder.clearCallingIdentity();
18343        try {
18344            Intent intent;
18345            if (oldUserId >= 0) {
18346                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18347                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18348                int count = profiles.size();
18349                for (int i = 0; i < count; i++) {
18350                    int profileUserId = profiles.get(i).id;
18351                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18352                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18353                            | Intent.FLAG_RECEIVER_FOREGROUND);
18354                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18355                    broadcastIntentLocked(null, null, intent,
18356                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18357                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18358                }
18359            }
18360            if (newUserId >= 0) {
18361                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18362                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18363                int count = profiles.size();
18364                for (int i = 0; i < count; i++) {
18365                    int profileUserId = profiles.get(i).id;
18366                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18367                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18368                            | Intent.FLAG_RECEIVER_FOREGROUND);
18369                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18370                    broadcastIntentLocked(null, null, intent,
18371                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18372                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18373                }
18374                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18375                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18376                        | Intent.FLAG_RECEIVER_FOREGROUND);
18377                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18378                broadcastIntentLocked(null, null, intent,
18379                        null, null, 0, null, null,
18380                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18381                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18382            }
18383        } finally {
18384            Binder.restoreCallingIdentity(ident);
18385        }
18386    }
18387
18388    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18389            final int newUserId) {
18390        final int N = mUserSwitchObservers.beginBroadcast();
18391        if (N > 0) {
18392            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18393                int mCount = 0;
18394                @Override
18395                public void sendResult(Bundle data) throws RemoteException {
18396                    synchronized (ActivityManagerService.this) {
18397                        if (mCurUserSwitchCallback == this) {
18398                            mCount++;
18399                            if (mCount == N) {
18400                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18401                            }
18402                        }
18403                    }
18404                }
18405            };
18406            synchronized (this) {
18407                uss.switching = true;
18408                mCurUserSwitchCallback = callback;
18409            }
18410            for (int i=0; i<N; i++) {
18411                try {
18412                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18413                            newUserId, callback);
18414                } catch (RemoteException e) {
18415                }
18416            }
18417        } else {
18418            synchronized (this) {
18419                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18420            }
18421        }
18422        mUserSwitchObservers.finishBroadcast();
18423    }
18424
18425    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18426        synchronized (this) {
18427            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18428            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18429        }
18430    }
18431
18432    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18433        mCurUserSwitchCallback = null;
18434        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18435        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18436                oldUserId, newUserId, uss));
18437    }
18438
18439    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18440        synchronized (this) {
18441            if (foreground) {
18442                moveUserToForeground(uss, oldUserId, newUserId);
18443            }
18444        }
18445
18446        completeSwitchAndInitalize(uss, newUserId, true, false);
18447    }
18448
18449    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18450        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18451        if (homeInFront) {
18452            startHomeActivityLocked(newUserId);
18453        } else {
18454            mStackSupervisor.resumeTopActivitiesLocked();
18455        }
18456        EventLogTags.writeAmSwitchUser(newUserId);
18457        getUserManagerLocked().userForeground(newUserId);
18458        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18459    }
18460
18461    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18462        completeSwitchAndInitalize(uss, newUserId, false, true);
18463    }
18464
18465    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18466            boolean clearInitializing, boolean clearSwitching) {
18467        boolean unfrozen = false;
18468        synchronized (this) {
18469            if (clearInitializing) {
18470                uss.initializing = false;
18471                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18472            }
18473            if (clearSwitching) {
18474                uss.switching = false;
18475            }
18476            if (!uss.switching && !uss.initializing) {
18477                mWindowManager.stopFreezingScreen();
18478                unfrozen = true;
18479            }
18480        }
18481        if (unfrozen) {
18482            final int N = mUserSwitchObservers.beginBroadcast();
18483            for (int i=0; i<N; i++) {
18484                try {
18485                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18486                } catch (RemoteException e) {
18487                }
18488            }
18489            mUserSwitchObservers.finishBroadcast();
18490        }
18491    }
18492
18493    void scheduleStartProfilesLocked() {
18494        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18495            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18496                    DateUtils.SECOND_IN_MILLIS);
18497        }
18498    }
18499
18500    void startProfilesLocked() {
18501        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18502        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18503                mCurrentUserId, false /* enabledOnly */);
18504        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18505        for (UserInfo user : profiles) {
18506            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18507                    && user.id != mCurrentUserId) {
18508                toStart.add(user);
18509            }
18510        }
18511        final int n = toStart.size();
18512        int i = 0;
18513        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18514            startUserInBackground(toStart.get(i).id);
18515        }
18516        if (i < n) {
18517            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18518        }
18519    }
18520
18521    void finishUserBoot(UserStartedState uss) {
18522        synchronized (this) {
18523            if (uss.mState == UserStartedState.STATE_BOOTING
18524                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18525                uss.mState = UserStartedState.STATE_RUNNING;
18526                final int userId = uss.mHandle.getIdentifier();
18527                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18528                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18529                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18530                broadcastIntentLocked(null, null, intent,
18531                        null, null, 0, null, null,
18532                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18533                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18534            }
18535        }
18536    }
18537
18538    void finishUserSwitch(UserStartedState uss) {
18539        synchronized (this) {
18540            finishUserBoot(uss);
18541
18542            startProfilesLocked();
18543
18544            int num = mUserLru.size();
18545            int i = 0;
18546            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18547                Integer oldUserId = mUserLru.get(i);
18548                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18549                if (oldUss == null) {
18550                    // Shouldn't happen, but be sane if it does.
18551                    mUserLru.remove(i);
18552                    num--;
18553                    continue;
18554                }
18555                if (oldUss.mState == UserStartedState.STATE_STOPPING
18556                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18557                    // This user is already stopping, doesn't count.
18558                    num--;
18559                    i++;
18560                    continue;
18561                }
18562                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18563                    // Owner and current can't be stopped, but count as running.
18564                    i++;
18565                    continue;
18566                }
18567                // This is a user to be stopped.
18568                stopUserLocked(oldUserId, null);
18569                num--;
18570                i++;
18571            }
18572        }
18573    }
18574
18575    @Override
18576    public int stopUser(final int userId, final IStopUserCallback callback) {
18577        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18578                != PackageManager.PERMISSION_GRANTED) {
18579            String msg = "Permission Denial: switchUser() from pid="
18580                    + Binder.getCallingPid()
18581                    + ", uid=" + Binder.getCallingUid()
18582                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18583            Slog.w(TAG, msg);
18584            throw new SecurityException(msg);
18585        }
18586        if (userId <= 0) {
18587            throw new IllegalArgumentException("Can't stop primary user " + userId);
18588        }
18589        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18590        synchronized (this) {
18591            return stopUserLocked(userId, callback);
18592        }
18593    }
18594
18595    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18596        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18597        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18598            return ActivityManager.USER_OP_IS_CURRENT;
18599        }
18600
18601        final UserStartedState uss = mStartedUsers.get(userId);
18602        if (uss == null) {
18603            // User is not started, nothing to do...  but we do need to
18604            // callback if requested.
18605            if (callback != null) {
18606                mHandler.post(new Runnable() {
18607                    @Override
18608                    public void run() {
18609                        try {
18610                            callback.userStopped(userId);
18611                        } catch (RemoteException e) {
18612                        }
18613                    }
18614                });
18615            }
18616            return ActivityManager.USER_OP_SUCCESS;
18617        }
18618
18619        if (callback != null) {
18620            uss.mStopCallbacks.add(callback);
18621        }
18622
18623        if (uss.mState != UserStartedState.STATE_STOPPING
18624                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18625            uss.mState = UserStartedState.STATE_STOPPING;
18626            updateStartedUserArrayLocked();
18627
18628            long ident = Binder.clearCallingIdentity();
18629            try {
18630                // We are going to broadcast ACTION_USER_STOPPING and then
18631                // once that is done send a final ACTION_SHUTDOWN and then
18632                // stop the user.
18633                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18634                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18635                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18636                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18637                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18638                // This is the result receiver for the final shutdown broadcast.
18639                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18640                    @Override
18641                    public void performReceive(Intent intent, int resultCode, String data,
18642                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18643                        finishUserStop(uss);
18644                    }
18645                };
18646                // This is the result receiver for the initial stopping broadcast.
18647                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18648                    @Override
18649                    public void performReceive(Intent intent, int resultCode, String data,
18650                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18651                        // On to the next.
18652                        synchronized (ActivityManagerService.this) {
18653                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18654                                // Whoops, we are being started back up.  Abort, abort!
18655                                return;
18656                            }
18657                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18658                        }
18659                        mBatteryStatsService.noteEvent(
18660                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18661                                Integer.toString(userId), userId);
18662                        mSystemServiceManager.stopUser(userId);
18663                        broadcastIntentLocked(null, null, shutdownIntent,
18664                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18665                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18666                    }
18667                };
18668                // Kick things off.
18669                broadcastIntentLocked(null, null, stoppingIntent,
18670                        null, stoppingReceiver, 0, null, null,
18671                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18672                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18673            } finally {
18674                Binder.restoreCallingIdentity(ident);
18675            }
18676        }
18677
18678        return ActivityManager.USER_OP_SUCCESS;
18679    }
18680
18681    void finishUserStop(UserStartedState uss) {
18682        final int userId = uss.mHandle.getIdentifier();
18683        boolean stopped;
18684        ArrayList<IStopUserCallback> callbacks;
18685        synchronized (this) {
18686            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18687            if (mStartedUsers.get(userId) != uss) {
18688                stopped = false;
18689            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18690                stopped = false;
18691            } else {
18692                stopped = true;
18693                // User can no longer run.
18694                mStartedUsers.remove(userId);
18695                mUserLru.remove(Integer.valueOf(userId));
18696                updateStartedUserArrayLocked();
18697
18698                // Clean up all state and processes associated with the user.
18699                // Kill all the processes for the user.
18700                forceStopUserLocked(userId, "finish user");
18701            }
18702
18703            // Explicitly remove the old information in mRecentTasks.
18704            removeRecentTasksForUserLocked(userId);
18705        }
18706
18707        for (int i=0; i<callbacks.size(); i++) {
18708            try {
18709                if (stopped) callbacks.get(i).userStopped(userId);
18710                else callbacks.get(i).userStopAborted(userId);
18711            } catch (RemoteException e) {
18712            }
18713        }
18714
18715        if (stopped) {
18716            mSystemServiceManager.cleanupUser(userId);
18717            synchronized (this) {
18718                mStackSupervisor.removeUserLocked(userId);
18719            }
18720        }
18721    }
18722
18723    @Override
18724    public UserInfo getCurrentUser() {
18725        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18726                != PackageManager.PERMISSION_GRANTED) && (
18727                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18728                != PackageManager.PERMISSION_GRANTED)) {
18729            String msg = "Permission Denial: getCurrentUser() from pid="
18730                    + Binder.getCallingPid()
18731                    + ", uid=" + Binder.getCallingUid()
18732                    + " requires " + INTERACT_ACROSS_USERS;
18733            Slog.w(TAG, msg);
18734            throw new SecurityException(msg);
18735        }
18736        synchronized (this) {
18737            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18738            return getUserManagerLocked().getUserInfo(userId);
18739        }
18740    }
18741
18742    int getCurrentUserIdLocked() {
18743        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18744    }
18745
18746    @Override
18747    public boolean isUserRunning(int userId, boolean orStopped) {
18748        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18749                != PackageManager.PERMISSION_GRANTED) {
18750            String msg = "Permission Denial: isUserRunning() from pid="
18751                    + Binder.getCallingPid()
18752                    + ", uid=" + Binder.getCallingUid()
18753                    + " requires " + INTERACT_ACROSS_USERS;
18754            Slog.w(TAG, msg);
18755            throw new SecurityException(msg);
18756        }
18757        synchronized (this) {
18758            return isUserRunningLocked(userId, orStopped);
18759        }
18760    }
18761
18762    boolean isUserRunningLocked(int userId, boolean orStopped) {
18763        UserStartedState state = mStartedUsers.get(userId);
18764        if (state == null) {
18765            return false;
18766        }
18767        if (orStopped) {
18768            return true;
18769        }
18770        return state.mState != UserStartedState.STATE_STOPPING
18771                && state.mState != UserStartedState.STATE_SHUTDOWN;
18772    }
18773
18774    @Override
18775    public int[] getRunningUserIds() {
18776        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18777                != PackageManager.PERMISSION_GRANTED) {
18778            String msg = "Permission Denial: isUserRunning() from pid="
18779                    + Binder.getCallingPid()
18780                    + ", uid=" + Binder.getCallingUid()
18781                    + " requires " + INTERACT_ACROSS_USERS;
18782            Slog.w(TAG, msg);
18783            throw new SecurityException(msg);
18784        }
18785        synchronized (this) {
18786            return mStartedUserArray;
18787        }
18788    }
18789
18790    private void updateStartedUserArrayLocked() {
18791        int num = 0;
18792        for (int i=0; i<mStartedUsers.size();  i++) {
18793            UserStartedState uss = mStartedUsers.valueAt(i);
18794            // This list does not include stopping users.
18795            if (uss.mState != UserStartedState.STATE_STOPPING
18796                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18797                num++;
18798            }
18799        }
18800        mStartedUserArray = new int[num];
18801        num = 0;
18802        for (int i=0; i<mStartedUsers.size();  i++) {
18803            UserStartedState uss = mStartedUsers.valueAt(i);
18804            if (uss.mState != UserStartedState.STATE_STOPPING
18805                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18806                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18807                num++;
18808            }
18809        }
18810    }
18811
18812    @Override
18813    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18814        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18815                != PackageManager.PERMISSION_GRANTED) {
18816            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18817                    + Binder.getCallingPid()
18818                    + ", uid=" + Binder.getCallingUid()
18819                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18820            Slog.w(TAG, msg);
18821            throw new SecurityException(msg);
18822        }
18823
18824        mUserSwitchObservers.register(observer);
18825    }
18826
18827    @Override
18828    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18829        mUserSwitchObservers.unregister(observer);
18830    }
18831
18832    private boolean userExists(int userId) {
18833        if (userId == 0) {
18834            return true;
18835        }
18836        UserManagerService ums = getUserManagerLocked();
18837        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18838    }
18839
18840    int[] getUsersLocked() {
18841        UserManagerService ums = getUserManagerLocked();
18842        return ums != null ? ums.getUserIds() : new int[] { 0 };
18843    }
18844
18845    UserManagerService getUserManagerLocked() {
18846        if (mUserManager == null) {
18847            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18848            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18849        }
18850        return mUserManager;
18851    }
18852
18853    private int applyUserId(int uid, int userId) {
18854        return UserHandle.getUid(userId, uid);
18855    }
18856
18857    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18858        if (info == null) return null;
18859        ApplicationInfo newInfo = new ApplicationInfo(info);
18860        newInfo.uid = applyUserId(info.uid, userId);
18861        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18862                + info.packageName;
18863        return newInfo;
18864    }
18865
18866    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18867        if (aInfo == null
18868                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18869            return aInfo;
18870        }
18871
18872        ActivityInfo info = new ActivityInfo(aInfo);
18873        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18874        return info;
18875    }
18876
18877    private final class LocalService extends ActivityManagerInternal {
18878        @Override
18879        public void goingToSleep() {
18880            ActivityManagerService.this.goingToSleep();
18881        }
18882
18883        @Override
18884        public void wakingUp() {
18885            ActivityManagerService.this.wakingUp();
18886        }
18887
18888        @Override
18889        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18890                String processName, String abiOverride, int uid, Runnable crashHandler) {
18891            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18892                    processName, abiOverride, uid, crashHandler);
18893        }
18894    }
18895
18896    /**
18897     * An implementation of IAppTask, that allows an app to manage its own tasks via
18898     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18899     * only the process that calls getAppTasks() can call the AppTask methods.
18900     */
18901    class AppTaskImpl extends IAppTask.Stub {
18902        private int mTaskId;
18903        private int mCallingUid;
18904
18905        public AppTaskImpl(int taskId, int callingUid) {
18906            mTaskId = taskId;
18907            mCallingUid = callingUid;
18908        }
18909
18910        private void checkCaller() {
18911            if (mCallingUid != Binder.getCallingUid()) {
18912                throw new SecurityException("Caller " + mCallingUid
18913                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18914            }
18915        }
18916
18917        @Override
18918        public void finishAndRemoveTask() {
18919            checkCaller();
18920
18921            synchronized (ActivityManagerService.this) {
18922                long origId = Binder.clearCallingIdentity();
18923                try {
18924                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18925                    if (tr == null) {
18926                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18927                    }
18928                    // Only kill the process if we are not a new document
18929                    int flags = tr.getBaseIntent().getFlags();
18930                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18931                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18932                    removeTaskByIdLocked(mTaskId,
18933                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18934                } finally {
18935                    Binder.restoreCallingIdentity(origId);
18936                }
18937            }
18938        }
18939
18940        @Override
18941        public ActivityManager.RecentTaskInfo getTaskInfo() {
18942            checkCaller();
18943
18944            synchronized (ActivityManagerService.this) {
18945                long origId = Binder.clearCallingIdentity();
18946                try {
18947                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18948                    if (tr == null) {
18949                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18950                    }
18951                    return createRecentTaskInfoFromTaskRecord(tr);
18952                } finally {
18953                    Binder.restoreCallingIdentity(origId);
18954                }
18955            }
18956        }
18957
18958        @Override
18959        public void moveToFront() {
18960            checkCaller();
18961
18962            final TaskRecord tr;
18963            synchronized (ActivityManagerService.this) {
18964                tr = recentTaskForIdLocked(mTaskId);
18965                if (tr == null) {
18966                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18967                }
18968                if (tr.getRootActivity() != null) {
18969                    moveTaskToFrontLocked(tr.taskId, 0, null);
18970                    return;
18971                }
18972            }
18973
18974            startActivityFromRecentsInner(tr.taskId, null);
18975        }
18976
18977        @Override
18978        public int startActivity(IBinder whoThread, String callingPackage,
18979                Intent intent, String resolvedType, Bundle options) {
18980            checkCaller();
18981
18982            int callingUser = UserHandle.getCallingUserId();
18983            TaskRecord tr;
18984            IApplicationThread appThread;
18985            synchronized (ActivityManagerService.this) {
18986                tr = recentTaskForIdLocked(mTaskId);
18987                if (tr == null) {
18988                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18989                }
18990                appThread = ApplicationThreadNative.asInterface(whoThread);
18991                if (appThread == null) {
18992                    throw new IllegalArgumentException("Bad app thread " + appThread);
18993                }
18994            }
18995            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18996                    resolvedType, null, null, null, null, 0, 0, null, null,
18997                    null, options, callingUser, null, tr);
18998        }
18999
19000        @Override
19001        public void setExcludeFromRecents(boolean exclude) {
19002            checkCaller();
19003
19004            synchronized (ActivityManagerService.this) {
19005                long origId = Binder.clearCallingIdentity();
19006                try {
19007                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19008                    if (tr == null) {
19009                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19010                    }
19011                    Intent intent = tr.getBaseIntent();
19012                    if (exclude) {
19013                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19014                    } else {
19015                        intent.setFlags(intent.getFlags()
19016                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19017                    }
19018                } finally {
19019                    Binder.restoreCallingIdentity(origId);
19020                }
19021            }
19022        }
19023    }
19024}
19025