ActivityManagerService.java revision 95cce9f382693ad13039d1a1fb15529017a20929
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            final int eventUserId = getChangingUserId();
1990            synchronized (ActivityManagerService.this) {
1991                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1992                    TaskRecord tr = mRecentTasks.get(i);
1993                    if (tr.userId != eventUserId) continue;
1994
1995                    ComponentName cn = tr.intent.getComponent();
1996                    if (cn != null && cn.getPackageName().equals(packageName)) {
1997                        // If the package name matches, remove the task and kill the process
1998                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1999                    }
2000                }
2001            }
2002        }
2003
2004        @Override
2005        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2006            onPackageModified(packageName);
2007            return true;
2008        }
2009
2010        @Override
2011        public void onPackageModified(String packageName) {
2012            final int eventUserId = getChangingUserId();
2013            final PackageManager pm = mContext.getPackageManager();
2014            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2015                    new ArrayList<Pair<Intent, Integer>>();
2016            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2017            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2018            // Copy the list of recent tasks so that we don't hold onto the lock on
2019            // ActivityManagerService for long periods while checking if components exist.
2020            synchronized (ActivityManagerService.this) {
2021                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2022                    TaskRecord tr = mRecentTasks.get(i);
2023                    if (tr.userId != eventUserId) continue;
2024
2025                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2026                }
2027            }
2028            // Check the recent tasks and filter out all tasks with components that no longer exist.
2029            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2030                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2031                ComponentName cn = p.first.getComponent();
2032                if (cn != null && cn.getPackageName().equals(packageName)) {
2033                    if (componentsKnownToExist.contains(cn)) {
2034                        // If we know that the component still exists in the package, then skip
2035                        continue;
2036                    }
2037                    try {
2038                        ActivityInfo info = pm.getActivityInfo(cn, eventUserId);
2039                        if (info != null && info.isEnabled()) {
2040                            componentsKnownToExist.add(cn);
2041                        } else {
2042                            tasksToRemove.add(p.second);
2043                        }
2044                    } catch (Exception e) {}
2045                }
2046            }
2047            // Prune all the tasks with removed components from the list of recent tasks
2048            synchronized (ActivityManagerService.this) {
2049                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2050                    // Remove the task but don't kill the process (since other components in that
2051                    // package may still be running and in the background)
2052                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2053                }
2054            }
2055        }
2056
2057        @Override
2058        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2059            // Force stop the specified packages
2060            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2061            if (packages != null) {
2062                for (String pkg : packages) {
2063                    synchronized (ActivityManagerService.this) {
2064                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2065                                userId, "finished booting")) {
2066                            return true;
2067                        }
2068                    }
2069                }
2070            }
2071            return false;
2072        }
2073    };
2074
2075    public void setSystemProcess() {
2076        try {
2077            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2078            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2079            ServiceManager.addService("meminfo", new MemBinder(this));
2080            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2081            ServiceManager.addService("dbinfo", new DbBinder(this));
2082            if (MONITOR_CPU_USAGE) {
2083                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2084            }
2085            ServiceManager.addService("permission", new PermissionController(this));
2086
2087            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2088                    "android", STOCK_PM_FLAGS);
2089            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2090
2091            synchronized (this) {
2092                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2093                app.persistent = true;
2094                app.pid = MY_PID;
2095                app.maxAdj = ProcessList.SYSTEM_ADJ;
2096                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2097                mProcessNames.put(app.processName, app.uid, app);
2098                synchronized (mPidsSelfLocked) {
2099                    mPidsSelfLocked.put(app.pid, app);
2100                }
2101                updateLruProcessLocked(app, false, null);
2102                updateOomAdjLocked();
2103            }
2104        } catch (PackageManager.NameNotFoundException e) {
2105            throw new RuntimeException(
2106                    "Unable to find android system package", e);
2107        }
2108    }
2109
2110    public void setWindowManager(WindowManagerService wm) {
2111        mWindowManager = wm;
2112        mStackSupervisor.setWindowManager(wm);
2113    }
2114
2115    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2116        mUsageStatsService = usageStatsManager;
2117    }
2118
2119    public void startObservingNativeCrashes() {
2120        final NativeCrashListener ncl = new NativeCrashListener(this);
2121        ncl.start();
2122    }
2123
2124    public IAppOpsService getAppOpsService() {
2125        return mAppOpsService;
2126    }
2127
2128    static class MemBinder extends Binder {
2129        ActivityManagerService mActivityManagerService;
2130        MemBinder(ActivityManagerService activityManagerService) {
2131            mActivityManagerService = activityManagerService;
2132        }
2133
2134        @Override
2135        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2136            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2137                    != PackageManager.PERMISSION_GRANTED) {
2138                pw.println("Permission Denial: can't dump meminfo from from pid="
2139                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2140                        + " without permission " + android.Manifest.permission.DUMP);
2141                return;
2142            }
2143
2144            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2145        }
2146    }
2147
2148    static class GraphicsBinder extends Binder {
2149        ActivityManagerService mActivityManagerService;
2150        GraphicsBinder(ActivityManagerService activityManagerService) {
2151            mActivityManagerService = activityManagerService;
2152        }
2153
2154        @Override
2155        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2156            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2157                    != PackageManager.PERMISSION_GRANTED) {
2158                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2159                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2160                        + " without permission " + android.Manifest.permission.DUMP);
2161                return;
2162            }
2163
2164            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2165        }
2166    }
2167
2168    static class DbBinder extends Binder {
2169        ActivityManagerService mActivityManagerService;
2170        DbBinder(ActivityManagerService activityManagerService) {
2171            mActivityManagerService = activityManagerService;
2172        }
2173
2174        @Override
2175        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2176            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2177                    != PackageManager.PERMISSION_GRANTED) {
2178                pw.println("Permission Denial: can't dump dbinfo from from pid="
2179                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2180                        + " without permission " + android.Manifest.permission.DUMP);
2181                return;
2182            }
2183
2184            mActivityManagerService.dumpDbInfo(fd, pw, args);
2185        }
2186    }
2187
2188    static class CpuBinder extends Binder {
2189        ActivityManagerService mActivityManagerService;
2190        CpuBinder(ActivityManagerService activityManagerService) {
2191            mActivityManagerService = activityManagerService;
2192        }
2193
2194        @Override
2195        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2196            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2197                    != PackageManager.PERMISSION_GRANTED) {
2198                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2199                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2200                        + " without permission " + android.Manifest.permission.DUMP);
2201                return;
2202            }
2203
2204            synchronized (mActivityManagerService.mProcessCpuTracker) {
2205                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2206                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2207                        SystemClock.uptimeMillis()));
2208            }
2209        }
2210    }
2211
2212    public static final class Lifecycle extends SystemService {
2213        private final ActivityManagerService mService;
2214
2215        public Lifecycle(Context context) {
2216            super(context);
2217            mService = new ActivityManagerService(context);
2218        }
2219
2220        @Override
2221        public void onStart() {
2222            mService.start();
2223        }
2224
2225        public ActivityManagerService getService() {
2226            return mService;
2227        }
2228    }
2229
2230    // Note: This method is invoked on the main thread but may need to attach various
2231    // handlers to other threads.  So take care to be explicit about the looper.
2232    public ActivityManagerService(Context systemContext) {
2233        mContext = systemContext;
2234        mFactoryTest = FactoryTest.getMode();
2235        mSystemThread = ActivityThread.currentActivityThread();
2236
2237        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2238
2239        mHandlerThread = new ServiceThread(TAG,
2240                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2241        mHandlerThread.start();
2242        mHandler = new MainHandler(mHandlerThread.getLooper());
2243
2244        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2245                "foreground", BROADCAST_FG_TIMEOUT, false);
2246        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2247                "background", BROADCAST_BG_TIMEOUT, true);
2248        mBroadcastQueues[0] = mFgBroadcastQueue;
2249        mBroadcastQueues[1] = mBgBroadcastQueue;
2250
2251        mServices = new ActiveServices(this);
2252        mProviderMap = new ProviderMap(this);
2253
2254        // TODO: Move creation of battery stats service outside of activity manager service.
2255        File dataDir = Environment.getDataDirectory();
2256        File systemDir = new File(dataDir, "system");
2257        systemDir.mkdirs();
2258        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2259        mBatteryStatsService.getActiveStatistics().readLocked();
2260        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2261        mOnBattery = DEBUG_POWER ? true
2262                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2263        mBatteryStatsService.getActiveStatistics().setCallback(this);
2264
2265        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2266
2267        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2268
2269        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2270
2271        // User 0 is the first and only user that runs at boot.
2272        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2273        mUserLru.add(Integer.valueOf(0));
2274        updateStartedUserArrayLocked();
2275
2276        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2277            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2278
2279        mConfiguration.setToDefaults();
2280        mConfiguration.setLocale(Locale.getDefault());
2281
2282        mConfigurationSeq = mConfiguration.seq = 1;
2283        mProcessCpuTracker.init();
2284
2285        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2286        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2287        mStackSupervisor = new ActivityStackSupervisor(this);
2288        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2289
2290        mProcessCpuThread = new Thread("CpuTracker") {
2291            @Override
2292            public void run() {
2293                while (true) {
2294                    try {
2295                        try {
2296                            synchronized(this) {
2297                                final long now = SystemClock.uptimeMillis();
2298                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2299                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2300                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2301                                //        + ", write delay=" + nextWriteDelay);
2302                                if (nextWriteDelay < nextCpuDelay) {
2303                                    nextCpuDelay = nextWriteDelay;
2304                                }
2305                                if (nextCpuDelay > 0) {
2306                                    mProcessCpuMutexFree.set(true);
2307                                    this.wait(nextCpuDelay);
2308                                }
2309                            }
2310                        } catch (InterruptedException e) {
2311                        }
2312                        updateCpuStatsNow();
2313                    } catch (Exception e) {
2314                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2315                    }
2316                }
2317            }
2318        };
2319
2320        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2321
2322        Watchdog.getInstance().addMonitor(this);
2323        Watchdog.getInstance().addThread(mHandler);
2324    }
2325
2326    public void setSystemServiceManager(SystemServiceManager mgr) {
2327        mSystemServiceManager = mgr;
2328    }
2329
2330    private void start() {
2331        Process.removeAllProcessGroups();
2332        mProcessCpuThread.start();
2333
2334        mBatteryStatsService.publish(mContext);
2335        mAppOpsService.publish(mContext);
2336        Slog.d("AppOps", "AppOpsService published");
2337        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2338    }
2339
2340    public void initPowerManagement() {
2341        mStackSupervisor.initPowerManagement();
2342        mBatteryStatsService.initPowerManagement();
2343    }
2344
2345    @Override
2346    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2347            throws RemoteException {
2348        if (code == SYSPROPS_TRANSACTION) {
2349            // We need to tell all apps about the system property change.
2350            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2351            synchronized(this) {
2352                final int NP = mProcessNames.getMap().size();
2353                for (int ip=0; ip<NP; ip++) {
2354                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2355                    final int NA = apps.size();
2356                    for (int ia=0; ia<NA; ia++) {
2357                        ProcessRecord app = apps.valueAt(ia);
2358                        if (app.thread != null) {
2359                            procs.add(app.thread.asBinder());
2360                        }
2361                    }
2362                }
2363            }
2364
2365            int N = procs.size();
2366            for (int i=0; i<N; i++) {
2367                Parcel data2 = Parcel.obtain();
2368                try {
2369                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2370                } catch (RemoteException e) {
2371                }
2372                data2.recycle();
2373            }
2374        }
2375        try {
2376            return super.onTransact(code, data, reply, flags);
2377        } catch (RuntimeException e) {
2378            // The activity manager only throws security exceptions, so let's
2379            // log all others.
2380            if (!(e instanceof SecurityException)) {
2381                Slog.wtf(TAG, "Activity Manager Crash", e);
2382            }
2383            throw e;
2384        }
2385    }
2386
2387    void updateCpuStats() {
2388        final long now = SystemClock.uptimeMillis();
2389        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2390            return;
2391        }
2392        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2393            synchronized (mProcessCpuThread) {
2394                mProcessCpuThread.notify();
2395            }
2396        }
2397    }
2398
2399    void updateCpuStatsNow() {
2400        synchronized (mProcessCpuTracker) {
2401            mProcessCpuMutexFree.set(false);
2402            final long now = SystemClock.uptimeMillis();
2403            boolean haveNewCpuStats = false;
2404
2405            if (MONITOR_CPU_USAGE &&
2406                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2407                mLastCpuTime.set(now);
2408                haveNewCpuStats = true;
2409                mProcessCpuTracker.update();
2410                //Slog.i(TAG, mProcessCpu.printCurrentState());
2411                //Slog.i(TAG, "Total CPU usage: "
2412                //        + mProcessCpu.getTotalCpuPercent() + "%");
2413
2414                // Slog the cpu usage if the property is set.
2415                if ("true".equals(SystemProperties.get("events.cpu"))) {
2416                    int user = mProcessCpuTracker.getLastUserTime();
2417                    int system = mProcessCpuTracker.getLastSystemTime();
2418                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2419                    int irq = mProcessCpuTracker.getLastIrqTime();
2420                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2421                    int idle = mProcessCpuTracker.getLastIdleTime();
2422
2423                    int total = user + system + iowait + irq + softIrq + idle;
2424                    if (total == 0) total = 1;
2425
2426                    EventLog.writeEvent(EventLogTags.CPU,
2427                            ((user+system+iowait+irq+softIrq) * 100) / total,
2428                            (user * 100) / total,
2429                            (system * 100) / total,
2430                            (iowait * 100) / total,
2431                            (irq * 100) / total,
2432                            (softIrq * 100) / total);
2433                }
2434            }
2435
2436            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2437            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2438            synchronized(bstats) {
2439                synchronized(mPidsSelfLocked) {
2440                    if (haveNewCpuStats) {
2441                        if (mOnBattery) {
2442                            int perc = bstats.startAddingCpuLocked();
2443                            int totalUTime = 0;
2444                            int totalSTime = 0;
2445                            final int N = mProcessCpuTracker.countStats();
2446                            for (int i=0; i<N; i++) {
2447                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2448                                if (!st.working) {
2449                                    continue;
2450                                }
2451                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2452                                int otherUTime = (st.rel_utime*perc)/100;
2453                                int otherSTime = (st.rel_stime*perc)/100;
2454                                totalUTime += otherUTime;
2455                                totalSTime += otherSTime;
2456                                if (pr != null) {
2457                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2458                                    if (ps == null || !ps.isActive()) {
2459                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2460                                                pr.info.uid, pr.processName);
2461                                    }
2462                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2463                                            st.rel_stime-otherSTime);
2464                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2465                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2466                                } else {
2467                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2468                                    if (ps == null || !ps.isActive()) {
2469                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2470                                                bstats.mapUid(st.uid), st.name);
2471                                    }
2472                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2473                                            st.rel_stime-otherSTime);
2474                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2475                                }
2476                            }
2477                            bstats.finishAddingCpuLocked(perc, totalUTime,
2478                                    totalSTime, cpuSpeedTimes);
2479                        }
2480                    }
2481                }
2482
2483                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2484                    mLastWriteTime = now;
2485                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2486                }
2487            }
2488        }
2489    }
2490
2491    @Override
2492    public void batteryNeedsCpuUpdate() {
2493        updateCpuStatsNow();
2494    }
2495
2496    @Override
2497    public void batteryPowerChanged(boolean onBattery) {
2498        // When plugging in, update the CPU stats first before changing
2499        // the plug state.
2500        updateCpuStatsNow();
2501        synchronized (this) {
2502            synchronized(mPidsSelfLocked) {
2503                mOnBattery = DEBUG_POWER ? true : onBattery;
2504            }
2505        }
2506    }
2507
2508    /**
2509     * Initialize the application bind args. These are passed to each
2510     * process when the bindApplication() IPC is sent to the process. They're
2511     * lazily setup to make sure the services are running when they're asked for.
2512     */
2513    private HashMap<String, IBinder> getCommonServicesLocked() {
2514        if (mAppBindArgs == null) {
2515            mAppBindArgs = new HashMap<String, IBinder>();
2516
2517            // Setup the application init args
2518            mAppBindArgs.put("package", ServiceManager.getService("package"));
2519            mAppBindArgs.put("window", ServiceManager.getService("window"));
2520            mAppBindArgs.put(Context.ALARM_SERVICE,
2521                    ServiceManager.getService(Context.ALARM_SERVICE));
2522        }
2523        return mAppBindArgs;
2524    }
2525
2526    final void setFocusedActivityLocked(ActivityRecord r) {
2527        if (mFocusedActivity != r) {
2528            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2529            mFocusedActivity = r;
2530            if (r.task != null && r.task.voiceInteractor != null) {
2531                startRunningVoiceLocked();
2532            } else {
2533                finishRunningVoiceLocked();
2534            }
2535            mStackSupervisor.setFocusedStack(r);
2536            if (r != null) {
2537                mWindowManager.setFocusedApp(r.appToken, true);
2538            }
2539            applyUpdateLockStateLocked(r);
2540        }
2541    }
2542
2543    final void clearFocusedActivity(ActivityRecord r) {
2544        if (mFocusedActivity == r) {
2545            mFocusedActivity = null;
2546        }
2547    }
2548
2549    @Override
2550    public void setFocusedStack(int stackId) {
2551        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2552        synchronized (ActivityManagerService.this) {
2553            ActivityStack stack = mStackSupervisor.getStack(stackId);
2554            if (stack != null) {
2555                ActivityRecord r = stack.topRunningActivityLocked(null);
2556                if (r != null) {
2557                    setFocusedActivityLocked(r);
2558                }
2559            }
2560        }
2561    }
2562
2563    @Override
2564    public void notifyActivityDrawn(IBinder token) {
2565        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2566        synchronized (this) {
2567            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2568            if (r != null) {
2569                r.task.stack.notifyActivityDrawnLocked(r);
2570            }
2571        }
2572    }
2573
2574    final void applyUpdateLockStateLocked(ActivityRecord r) {
2575        // Modifications to the UpdateLock state are done on our handler, outside
2576        // the activity manager's locks.  The new state is determined based on the
2577        // state *now* of the relevant activity record.  The object is passed to
2578        // the handler solely for logging detail, not to be consulted/modified.
2579        final boolean nextState = r != null && r.immersive;
2580        mHandler.sendMessage(
2581                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2582    }
2583
2584    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2585        Message msg = Message.obtain();
2586        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2587        msg.obj = r.task.askedCompatMode ? null : r;
2588        mHandler.sendMessage(msg);
2589    }
2590
2591    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2592            String what, Object obj, ProcessRecord srcApp) {
2593        app.lastActivityTime = now;
2594
2595        if (app.activities.size() > 0) {
2596            // Don't want to touch dependent processes that are hosting activities.
2597            return index;
2598        }
2599
2600        int lrui = mLruProcesses.lastIndexOf(app);
2601        if (lrui < 0) {
2602            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2603                    + what + " " + obj + " from " + srcApp);
2604            return index;
2605        }
2606
2607        if (lrui >= index) {
2608            // Don't want to cause this to move dependent processes *back* in the
2609            // list as if they were less frequently used.
2610            return index;
2611        }
2612
2613        if (lrui >= mLruProcessActivityStart) {
2614            // Don't want to touch dependent processes that are hosting activities.
2615            return index;
2616        }
2617
2618        mLruProcesses.remove(lrui);
2619        if (index > 0) {
2620            index--;
2621        }
2622        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2623                + " in LRU list: " + app);
2624        mLruProcesses.add(index, app);
2625        return index;
2626    }
2627
2628    final void removeLruProcessLocked(ProcessRecord app) {
2629        int lrui = mLruProcesses.lastIndexOf(app);
2630        if (lrui >= 0) {
2631            if (!app.killed) {
2632                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2633                Process.killProcessQuiet(app.pid);
2634                Process.killProcessGroup(app.info.uid, app.pid);
2635            }
2636            if (lrui <= mLruProcessActivityStart) {
2637                mLruProcessActivityStart--;
2638            }
2639            if (lrui <= mLruProcessServiceStart) {
2640                mLruProcessServiceStart--;
2641            }
2642            mLruProcesses.remove(lrui);
2643        }
2644    }
2645
2646    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2647            ProcessRecord client) {
2648        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2649                || app.treatLikeActivity;
2650        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2651        if (!activityChange && hasActivity) {
2652            // The process has activities, so we are only allowing activity-based adjustments
2653            // to move it.  It should be kept in the front of the list with other
2654            // processes that have activities, and we don't want those to change their
2655            // order except due to activity operations.
2656            return;
2657        }
2658
2659        mLruSeq++;
2660        final long now = SystemClock.uptimeMillis();
2661        app.lastActivityTime = now;
2662
2663        // First a quick reject: if the app is already at the position we will
2664        // put it, then there is nothing to do.
2665        if (hasActivity) {
2666            final int N = mLruProcesses.size();
2667            if (N > 0 && mLruProcesses.get(N-1) == app) {
2668                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2669                return;
2670            }
2671        } else {
2672            if (mLruProcessServiceStart > 0
2673                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2674                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2675                return;
2676            }
2677        }
2678
2679        int lrui = mLruProcesses.lastIndexOf(app);
2680
2681        if (app.persistent && lrui >= 0) {
2682            // We don't care about the position of persistent processes, as long as
2683            // they are in the list.
2684            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2685            return;
2686        }
2687
2688        /* In progress: compute new position first, so we can avoid doing work
2689           if the process is not actually going to move.  Not yet working.
2690        int addIndex;
2691        int nextIndex;
2692        boolean inActivity = false, inService = false;
2693        if (hasActivity) {
2694            // Process has activities, put it at the very tipsy-top.
2695            addIndex = mLruProcesses.size();
2696            nextIndex = mLruProcessServiceStart;
2697            inActivity = true;
2698        } else if (hasService) {
2699            // Process has services, put it at the top of the service list.
2700            addIndex = mLruProcessActivityStart;
2701            nextIndex = mLruProcessServiceStart;
2702            inActivity = true;
2703            inService = true;
2704        } else  {
2705            // Process not otherwise of interest, it goes to the top of the non-service area.
2706            addIndex = mLruProcessServiceStart;
2707            if (client != null) {
2708                int clientIndex = mLruProcesses.lastIndexOf(client);
2709                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2710                        + app);
2711                if (clientIndex >= 0 && addIndex > clientIndex) {
2712                    addIndex = clientIndex;
2713                }
2714            }
2715            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2716        }
2717
2718        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2719                + mLruProcessActivityStart + "): " + app);
2720        */
2721
2722        if (lrui >= 0) {
2723            if (lrui < mLruProcessActivityStart) {
2724                mLruProcessActivityStart--;
2725            }
2726            if (lrui < mLruProcessServiceStart) {
2727                mLruProcessServiceStart--;
2728            }
2729            /*
2730            if (addIndex > lrui) {
2731                addIndex--;
2732            }
2733            if (nextIndex > lrui) {
2734                nextIndex--;
2735            }
2736            */
2737            mLruProcesses.remove(lrui);
2738        }
2739
2740        /*
2741        mLruProcesses.add(addIndex, app);
2742        if (inActivity) {
2743            mLruProcessActivityStart++;
2744        }
2745        if (inService) {
2746            mLruProcessActivityStart++;
2747        }
2748        */
2749
2750        int nextIndex;
2751        if (hasActivity) {
2752            final int N = mLruProcesses.size();
2753            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2754                // Process doesn't have activities, but has clients with
2755                // activities...  move it up, but one below the top (the top
2756                // should always have a real activity).
2757                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2758                mLruProcesses.add(N-1, app);
2759                // To keep it from spamming the LRU list (by making a bunch of clients),
2760                // we will push down any other entries owned by the app.
2761                final int uid = app.info.uid;
2762                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2763                    ProcessRecord subProc = mLruProcesses.get(i);
2764                    if (subProc.info.uid == uid) {
2765                        // We want to push this one down the list.  If the process after
2766                        // it is for the same uid, however, don't do so, because we don't
2767                        // want them internally to be re-ordered.
2768                        if (mLruProcesses.get(i-1).info.uid != uid) {
2769                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2770                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2771                            ProcessRecord tmp = mLruProcesses.get(i);
2772                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2773                            mLruProcesses.set(i-1, tmp);
2774                            i--;
2775                        }
2776                    } else {
2777                        // A gap, we can stop here.
2778                        break;
2779                    }
2780                }
2781            } else {
2782                // Process has activities, put it at the very tipsy-top.
2783                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2784                mLruProcesses.add(app);
2785            }
2786            nextIndex = mLruProcessServiceStart;
2787        } else if (hasService) {
2788            // Process has services, put it at the top of the service list.
2789            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2790            mLruProcesses.add(mLruProcessActivityStart, app);
2791            nextIndex = mLruProcessServiceStart;
2792            mLruProcessActivityStart++;
2793        } else  {
2794            // Process not otherwise of interest, it goes to the top of the non-service area.
2795            int index = mLruProcessServiceStart;
2796            if (client != null) {
2797                // If there is a client, don't allow the process to be moved up higher
2798                // in the list than that client.
2799                int clientIndex = mLruProcesses.lastIndexOf(client);
2800                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2801                        + " when updating " + app);
2802                if (clientIndex <= lrui) {
2803                    // Don't allow the client index restriction to push it down farther in the
2804                    // list than it already is.
2805                    clientIndex = lrui;
2806                }
2807                if (clientIndex >= 0 && index > clientIndex) {
2808                    index = clientIndex;
2809                }
2810            }
2811            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2812            mLruProcesses.add(index, app);
2813            nextIndex = index-1;
2814            mLruProcessActivityStart++;
2815            mLruProcessServiceStart++;
2816        }
2817
2818        // If the app is currently using a content provider or service,
2819        // bump those processes as well.
2820        for (int j=app.connections.size()-1; j>=0; j--) {
2821            ConnectionRecord cr = app.connections.valueAt(j);
2822            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2823                    && cr.binding.service.app != null
2824                    && cr.binding.service.app.lruSeq != mLruSeq
2825                    && !cr.binding.service.app.persistent) {
2826                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2827                        "service connection", cr, app);
2828            }
2829        }
2830        for (int j=app.conProviders.size()-1; j>=0; j--) {
2831            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2832            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2833                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2834                        "provider reference", cpr, app);
2835            }
2836        }
2837    }
2838
2839    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2840        if (uid == Process.SYSTEM_UID) {
2841            // The system gets to run in any process.  If there are multiple
2842            // processes with the same uid, just pick the first (this
2843            // should never happen).
2844            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2845            if (procs == null) return null;
2846            final int N = procs.size();
2847            for (int i = 0; i < N; i++) {
2848                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2849            }
2850        }
2851        ProcessRecord proc = mProcessNames.get(processName, uid);
2852        if (false && proc != null && !keepIfLarge
2853                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2854                && proc.lastCachedPss >= 4000) {
2855            // Turn this condition on to cause killing to happen regularly, for testing.
2856            if (proc.baseProcessTracker != null) {
2857                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2858            }
2859            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2860        } else if (proc != null && !keepIfLarge
2861                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2862                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2863            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2864            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2865                if (proc.baseProcessTracker != null) {
2866                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2867                }
2868                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2869            }
2870        }
2871        return proc;
2872    }
2873
2874    void ensurePackageDexOpt(String packageName) {
2875        IPackageManager pm = AppGlobals.getPackageManager();
2876        try {
2877            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2878                mDidDexOpt = true;
2879            }
2880        } catch (RemoteException e) {
2881        }
2882    }
2883
2884    boolean isNextTransitionForward() {
2885        int transit = mWindowManager.getPendingAppTransition();
2886        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2887                || transit == AppTransition.TRANSIT_TASK_OPEN
2888                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2889    }
2890
2891    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2892            String processName, String abiOverride, int uid, Runnable crashHandler) {
2893        synchronized(this) {
2894            ApplicationInfo info = new ApplicationInfo();
2895            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2896            // For isolated processes, the former contains the parent's uid and the latter the
2897            // actual uid of the isolated process.
2898            // In the special case introduced by this method (which is, starting an isolated
2899            // process directly from the SystemServer without an actual parent app process) the
2900            // closest thing to a parent's uid is SYSTEM_UID.
2901            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2902            // the |isolated| logic in the ProcessRecord constructor.
2903            info.uid = Process.SYSTEM_UID;
2904            info.processName = processName;
2905            info.className = entryPoint;
2906            info.packageName = "android";
2907            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2908                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2909                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2910                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2911                    crashHandler);
2912            return proc != null ? proc.pid : 0;
2913        }
2914    }
2915
2916    final ProcessRecord startProcessLocked(String processName,
2917            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2918            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2919            boolean isolated, boolean keepIfLarge) {
2920        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2921                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2922                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2923                null /* crashHandler */);
2924    }
2925
2926    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2927            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2928            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2929            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2930        long startTime = SystemClock.elapsedRealtime();
2931        ProcessRecord app;
2932        if (!isolated) {
2933            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2934            checkTime(startTime, "startProcess: after getProcessRecord");
2935        } else {
2936            // If this is an isolated process, it can't re-use an existing process.
2937            app = null;
2938        }
2939        // We don't have to do anything more if:
2940        // (1) There is an existing application record; and
2941        // (2) The caller doesn't think it is dead, OR there is no thread
2942        //     object attached to it so we know it couldn't have crashed; and
2943        // (3) There is a pid assigned to it, so it is either starting or
2944        //     already running.
2945        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2946                + " app=" + app + " knownToBeDead=" + knownToBeDead
2947                + " thread=" + (app != null ? app.thread : null)
2948                + " pid=" + (app != null ? app.pid : -1));
2949        if (app != null && app.pid > 0) {
2950            if (!knownToBeDead || app.thread == null) {
2951                // We already have the app running, or are waiting for it to
2952                // come up (we have a pid but not yet its thread), so keep it.
2953                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2954                // If this is a new package in the process, add the package to the list
2955                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2956                checkTime(startTime, "startProcess: done, added package to proc");
2957                return app;
2958            }
2959
2960            // An application record is attached to a previous process,
2961            // clean it up now.
2962            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2963            checkTime(startTime, "startProcess: bad proc running, killing");
2964            Process.killProcessGroup(app.info.uid, app.pid);
2965            handleAppDiedLocked(app, true, true);
2966            checkTime(startTime, "startProcess: done killing old proc");
2967        }
2968
2969        String hostingNameStr = hostingName != null
2970                ? hostingName.flattenToShortString() : null;
2971
2972        if (!isolated) {
2973            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2974                // If we are in the background, then check to see if this process
2975                // is bad.  If so, we will just silently fail.
2976                if (mBadProcesses.get(info.processName, info.uid) != null) {
2977                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2978                            + "/" + info.processName);
2979                    return null;
2980                }
2981            } else {
2982                // When the user is explicitly starting a process, then clear its
2983                // crash count so that we won't make it bad until they see at
2984                // least one crash dialog again, and make the process good again
2985                // if it had been bad.
2986                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2987                        + "/" + info.processName);
2988                mProcessCrashTimes.remove(info.processName, info.uid);
2989                if (mBadProcesses.get(info.processName, info.uid) != null) {
2990                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2991                            UserHandle.getUserId(info.uid), info.uid,
2992                            info.processName);
2993                    mBadProcesses.remove(info.processName, info.uid);
2994                    if (app != null) {
2995                        app.bad = false;
2996                    }
2997                }
2998            }
2999        }
3000
3001        if (app == null) {
3002            checkTime(startTime, "startProcess: creating new process record");
3003            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3004            app.crashHandler = crashHandler;
3005            if (app == null) {
3006                Slog.w(TAG, "Failed making new process record for "
3007                        + processName + "/" + info.uid + " isolated=" + isolated);
3008                return null;
3009            }
3010            mProcessNames.put(processName, app.uid, app);
3011            if (isolated) {
3012                mIsolatedProcesses.put(app.uid, app);
3013            }
3014            checkTime(startTime, "startProcess: done creating new process record");
3015        } else {
3016            // If this is a new package in the process, add the package to the list
3017            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3018            checkTime(startTime, "startProcess: added package to existing proc");
3019        }
3020
3021        // If the system is not ready yet, then hold off on starting this
3022        // process until it is.
3023        if (!mProcessesReady
3024                && !isAllowedWhileBooting(info)
3025                && !allowWhileBooting) {
3026            if (!mProcessesOnHold.contains(app)) {
3027                mProcessesOnHold.add(app);
3028            }
3029            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3030            checkTime(startTime, "startProcess: returning with proc on hold");
3031            return app;
3032        }
3033
3034        checkTime(startTime, "startProcess: stepping in to startProcess");
3035        startProcessLocked(
3036                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3037        checkTime(startTime, "startProcess: done starting proc!");
3038        return (app.pid != 0) ? app : null;
3039    }
3040
3041    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3042        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3043    }
3044
3045    private final void startProcessLocked(ProcessRecord app,
3046            String hostingType, String hostingNameStr) {
3047        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3048                null /* entryPoint */, null /* entryPointArgs */);
3049    }
3050
3051    private final void startProcessLocked(ProcessRecord app, String hostingType,
3052            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3053        long startTime = SystemClock.elapsedRealtime();
3054        if (app.pid > 0 && app.pid != MY_PID) {
3055            checkTime(startTime, "startProcess: removing from pids map");
3056            synchronized (mPidsSelfLocked) {
3057                mPidsSelfLocked.remove(app.pid);
3058                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3059            }
3060            checkTime(startTime, "startProcess: done removing from pids map");
3061            app.setPid(0);
3062        }
3063
3064        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3065                "startProcessLocked removing on hold: " + app);
3066        mProcessesOnHold.remove(app);
3067
3068        checkTime(startTime, "startProcess: starting to update cpu stats");
3069        updateCpuStats();
3070        checkTime(startTime, "startProcess: done updating cpu stats");
3071
3072        try {
3073            int uid = app.uid;
3074
3075            int[] gids = null;
3076            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3077            if (!app.isolated) {
3078                int[] permGids = null;
3079                try {
3080                    checkTime(startTime, "startProcess: getting gids from package manager");
3081                    final PackageManager pm = mContext.getPackageManager();
3082                    permGids = pm.getPackageGids(app.info.packageName);
3083
3084                    if (Environment.isExternalStorageEmulated()) {
3085                        checkTime(startTime, "startProcess: checking external storage perm");
3086                        if (pm.checkPermission(
3087                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3088                                app.info.packageName) == PERMISSION_GRANTED) {
3089                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3090                        } else {
3091                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3092                        }
3093                    }
3094                } catch (PackageManager.NameNotFoundException e) {
3095                    Slog.w(TAG, "Unable to retrieve gids", e);
3096                }
3097
3098                /*
3099                 * Add shared application and profile GIDs so applications can share some
3100                 * resources like shared libraries and access user-wide resources
3101                 */
3102                if (permGids == null) {
3103                    gids = new int[2];
3104                } else {
3105                    gids = new int[permGids.length + 2];
3106                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3107                }
3108                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3109                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3110            }
3111            checkTime(startTime, "startProcess: building args");
3112            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3113                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3114                        && mTopComponent != null
3115                        && app.processName.equals(mTopComponent.getPackageName())) {
3116                    uid = 0;
3117                }
3118                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3119                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3120                    uid = 0;
3121                }
3122            }
3123            int debugFlags = 0;
3124            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3125                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3126                // Also turn on CheckJNI for debuggable apps. It's quite
3127                // awkward to turn on otherwise.
3128                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3129            }
3130            // Run the app in safe mode if its manifest requests so or the
3131            // system is booted in safe mode.
3132            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3133                mSafeMode == true) {
3134                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3135            }
3136            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3137                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3138            }
3139            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3140                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3141            }
3142            if ("1".equals(SystemProperties.get("debug.assert"))) {
3143                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3144            }
3145
3146            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3147            if (requiredAbi == null) {
3148                requiredAbi = Build.SUPPORTED_ABIS[0];
3149            }
3150
3151            String instructionSet = null;
3152            if (app.info.primaryCpuAbi != null) {
3153                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3154            }
3155
3156            // Start the process.  It will either succeed and return a result containing
3157            // the PID of the new process, or else throw a RuntimeException.
3158            boolean isActivityProcess = (entryPoint == null);
3159            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3160            checkTime(startTime, "startProcess: asking zygote to start proc");
3161            Process.ProcessStartResult startResult = Process.start(entryPoint,
3162                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3163                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3164                    entryPointArgs);
3165            checkTime(startTime, "startProcess: returned from zygote!");
3166
3167            if (app.isolated) {
3168                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3169            }
3170            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3171            checkTime(startTime, "startProcess: done updating battery stats");
3172
3173            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3174                    UserHandle.getUserId(uid), startResult.pid, uid,
3175                    app.processName, hostingType,
3176                    hostingNameStr != null ? hostingNameStr : "");
3177
3178            if (app.persistent) {
3179                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3180            }
3181
3182            checkTime(startTime, "startProcess: building log message");
3183            StringBuilder buf = mStringBuilder;
3184            buf.setLength(0);
3185            buf.append("Start proc ");
3186            buf.append(app.processName);
3187            if (!isActivityProcess) {
3188                buf.append(" [");
3189                buf.append(entryPoint);
3190                buf.append("]");
3191            }
3192            buf.append(" for ");
3193            buf.append(hostingType);
3194            if (hostingNameStr != null) {
3195                buf.append(" ");
3196                buf.append(hostingNameStr);
3197            }
3198            buf.append(": pid=");
3199            buf.append(startResult.pid);
3200            buf.append(" uid=");
3201            buf.append(uid);
3202            buf.append(" gids={");
3203            if (gids != null) {
3204                for (int gi=0; gi<gids.length; gi++) {
3205                    if (gi != 0) buf.append(", ");
3206                    buf.append(gids[gi]);
3207
3208                }
3209            }
3210            buf.append("}");
3211            if (requiredAbi != null) {
3212                buf.append(" abi=");
3213                buf.append(requiredAbi);
3214            }
3215            Slog.i(TAG, buf.toString());
3216            app.setPid(startResult.pid);
3217            app.usingWrapper = startResult.usingWrapper;
3218            app.removed = false;
3219            app.killed = false;
3220            app.killedByAm = false;
3221            checkTime(startTime, "startProcess: starting to update pids map");
3222            synchronized (mPidsSelfLocked) {
3223                this.mPidsSelfLocked.put(startResult.pid, app);
3224                if (isActivityProcess) {
3225                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3226                    msg.obj = app;
3227                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3228                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3229                }
3230            }
3231            checkTime(startTime, "startProcess: done updating pids map");
3232        } catch (RuntimeException e) {
3233            // XXX do better error recovery.
3234            app.setPid(0);
3235            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3236            if (app.isolated) {
3237                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3238            }
3239            Slog.e(TAG, "Failure starting process " + app.processName, e);
3240        }
3241    }
3242
3243    void updateUsageStats(ActivityRecord component, boolean resumed) {
3244        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3245        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3246        if (resumed) {
3247            if (mUsageStatsService != null) {
3248                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3249                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3250            }
3251            synchronized (stats) {
3252                stats.noteActivityResumedLocked(component.app.uid);
3253            }
3254        } else {
3255            if (mUsageStatsService != null) {
3256                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3257                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3258            }
3259            synchronized (stats) {
3260                stats.noteActivityPausedLocked(component.app.uid);
3261            }
3262        }
3263    }
3264
3265    Intent getHomeIntent() {
3266        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3267        intent.setComponent(mTopComponent);
3268        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3269            intent.addCategory(Intent.CATEGORY_HOME);
3270        }
3271        return intent;
3272    }
3273
3274    boolean startHomeActivityLocked(int userId) {
3275        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3276                && mTopAction == null) {
3277            // We are running in factory test mode, but unable to find
3278            // the factory test app, so just sit around displaying the
3279            // error message and don't try to start anything.
3280            return false;
3281        }
3282        Intent intent = getHomeIntent();
3283        ActivityInfo aInfo =
3284            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3285        if (aInfo != null) {
3286            intent.setComponent(new ComponentName(
3287                    aInfo.applicationInfo.packageName, aInfo.name));
3288            // Don't do this if the home app is currently being
3289            // instrumented.
3290            aInfo = new ActivityInfo(aInfo);
3291            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3292            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3293                    aInfo.applicationInfo.uid, true);
3294            if (app == null || app.instrumentationClass == null) {
3295                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3296                mStackSupervisor.startHomeActivity(intent, aInfo);
3297            }
3298        }
3299
3300        return true;
3301    }
3302
3303    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3304        ActivityInfo ai = null;
3305        ComponentName comp = intent.getComponent();
3306        try {
3307            if (comp != null) {
3308                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3309            } else {
3310                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3311                        intent,
3312                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3313                            flags, userId);
3314
3315                if (info != null) {
3316                    ai = info.activityInfo;
3317                }
3318            }
3319        } catch (RemoteException e) {
3320            // ignore
3321        }
3322
3323        return ai;
3324    }
3325
3326    /**
3327     * Starts the "new version setup screen" if appropriate.
3328     */
3329    void startSetupActivityLocked() {
3330        // Only do this once per boot.
3331        if (mCheckedForSetup) {
3332            return;
3333        }
3334
3335        // We will show this screen if the current one is a different
3336        // version than the last one shown, and we are not running in
3337        // low-level factory test mode.
3338        final ContentResolver resolver = mContext.getContentResolver();
3339        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3340                Settings.Global.getInt(resolver,
3341                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3342            mCheckedForSetup = true;
3343
3344            // See if we should be showing the platform update setup UI.
3345            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3346            List<ResolveInfo> ris = mContext.getPackageManager()
3347                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3348
3349            // We don't allow third party apps to replace this.
3350            ResolveInfo ri = null;
3351            for (int i=0; ris != null && i<ris.size(); i++) {
3352                if ((ris.get(i).activityInfo.applicationInfo.flags
3353                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3354                    ri = ris.get(i);
3355                    break;
3356                }
3357            }
3358
3359            if (ri != null) {
3360                String vers = ri.activityInfo.metaData != null
3361                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3362                        : null;
3363                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3364                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3365                            Intent.METADATA_SETUP_VERSION);
3366                }
3367                String lastVers = Settings.Secure.getString(
3368                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3369                if (vers != null && !vers.equals(lastVers)) {
3370                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3371                    intent.setComponent(new ComponentName(
3372                            ri.activityInfo.packageName, ri.activityInfo.name));
3373                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3374                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3375                            null);
3376                }
3377            }
3378        }
3379    }
3380
3381    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3382        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3383    }
3384
3385    void enforceNotIsolatedCaller(String caller) {
3386        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3387            throw new SecurityException("Isolated process not allowed to call " + caller);
3388        }
3389    }
3390
3391    void enforceShellRestriction(String restriction, int userHandle) {
3392        if (Binder.getCallingUid() == Process.SHELL_UID) {
3393            if (userHandle < 0
3394                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3395                throw new SecurityException("Shell does not have permission to access user "
3396                        + userHandle);
3397            }
3398        }
3399    }
3400
3401    @Override
3402    public int getFrontActivityScreenCompatMode() {
3403        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3404        synchronized (this) {
3405            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3406        }
3407    }
3408
3409    @Override
3410    public void setFrontActivityScreenCompatMode(int mode) {
3411        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3412                "setFrontActivityScreenCompatMode");
3413        synchronized (this) {
3414            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3415        }
3416    }
3417
3418    @Override
3419    public int getPackageScreenCompatMode(String packageName) {
3420        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3421        synchronized (this) {
3422            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3423        }
3424    }
3425
3426    @Override
3427    public void setPackageScreenCompatMode(String packageName, int mode) {
3428        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3429                "setPackageScreenCompatMode");
3430        synchronized (this) {
3431            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3432        }
3433    }
3434
3435    @Override
3436    public boolean getPackageAskScreenCompat(String packageName) {
3437        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3438        synchronized (this) {
3439            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3440        }
3441    }
3442
3443    @Override
3444    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3445        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3446                "setPackageAskScreenCompat");
3447        synchronized (this) {
3448            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3449        }
3450    }
3451
3452    private void dispatchProcessesChanged() {
3453        int N;
3454        synchronized (this) {
3455            N = mPendingProcessChanges.size();
3456            if (mActiveProcessChanges.length < N) {
3457                mActiveProcessChanges = new ProcessChangeItem[N];
3458            }
3459            mPendingProcessChanges.toArray(mActiveProcessChanges);
3460            mAvailProcessChanges.addAll(mPendingProcessChanges);
3461            mPendingProcessChanges.clear();
3462            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3463        }
3464
3465        int i = mProcessObservers.beginBroadcast();
3466        while (i > 0) {
3467            i--;
3468            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3469            if (observer != null) {
3470                try {
3471                    for (int j=0; j<N; j++) {
3472                        ProcessChangeItem item = mActiveProcessChanges[j];
3473                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3474                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3475                                    + item.pid + " uid=" + item.uid + ": "
3476                                    + item.foregroundActivities);
3477                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3478                                    item.foregroundActivities);
3479                        }
3480                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3481                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3482                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3483                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3484                        }
3485                    }
3486                } catch (RemoteException e) {
3487                }
3488            }
3489        }
3490        mProcessObservers.finishBroadcast();
3491    }
3492
3493    private void dispatchProcessDied(int pid, int uid) {
3494        int i = mProcessObservers.beginBroadcast();
3495        while (i > 0) {
3496            i--;
3497            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3498            if (observer != null) {
3499                try {
3500                    observer.onProcessDied(pid, uid);
3501                } catch (RemoteException e) {
3502                }
3503            }
3504        }
3505        mProcessObservers.finishBroadcast();
3506    }
3507
3508    @Override
3509    public final int startActivity(IApplicationThread caller, String callingPackage,
3510            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3511            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3512        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3513            resultWho, requestCode, startFlags, profilerInfo, options,
3514            UserHandle.getCallingUserId());
3515    }
3516
3517    @Override
3518    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3519            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3520            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3521        enforceNotIsolatedCaller("startActivity");
3522        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3523                false, ALLOW_FULL_ONLY, "startActivity", null);
3524        // TODO: Switch to user app stacks here.
3525        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3526                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3527                profilerInfo, null, null, options, userId, null, null);
3528    }
3529
3530    @Override
3531    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3532            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3533            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3534
3535        // This is very dangerous -- it allows you to perform a start activity (including
3536        // permission grants) as any app that may launch one of your own activities.  So
3537        // we will only allow this to be done from activities that are part of the core framework,
3538        // and then only when they are running as the system.
3539        final ActivityRecord sourceRecord;
3540        final int targetUid;
3541        final String targetPackage;
3542        synchronized (this) {
3543            if (resultTo == null) {
3544                throw new SecurityException("Must be called from an activity");
3545            }
3546            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3547            if (sourceRecord == null) {
3548                throw new SecurityException("Called with bad activity token: " + resultTo);
3549            }
3550            if (!sourceRecord.info.packageName.equals("android")) {
3551                throw new SecurityException(
3552                        "Must be called from an activity that is declared in the android package");
3553            }
3554            if (sourceRecord.app == null) {
3555                throw new SecurityException("Called without a process attached to activity");
3556            }
3557            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3558                // This is still okay, as long as this activity is running under the
3559                // uid of the original calling activity.
3560                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3561                    throw new SecurityException(
3562                            "Calling activity in uid " + sourceRecord.app.uid
3563                                    + " must be system uid or original calling uid "
3564                                    + sourceRecord.launchedFromUid);
3565                }
3566            }
3567            targetUid = sourceRecord.launchedFromUid;
3568            targetPackage = sourceRecord.launchedFromPackage;
3569        }
3570
3571        // TODO: Switch to user app stacks here.
3572        try {
3573            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3574                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3575                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3576            return ret;
3577        } catch (SecurityException e) {
3578            // XXX need to figure out how to propagate to original app.
3579            // A SecurityException here is generally actually a fault of the original
3580            // calling activity (such as a fairly granting permissions), so propagate it
3581            // back to them.
3582            /*
3583            StringBuilder msg = new StringBuilder();
3584            msg.append("While launching");
3585            msg.append(intent.toString());
3586            msg.append(": ");
3587            msg.append(e.getMessage());
3588            */
3589            throw e;
3590        }
3591    }
3592
3593    @Override
3594    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3595            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3596            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3597        enforceNotIsolatedCaller("startActivityAndWait");
3598        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3599                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3600        WaitResult res = new WaitResult();
3601        // TODO: Switch to user app stacks here.
3602        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3603                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3604                options, userId, null, null);
3605        return res;
3606    }
3607
3608    @Override
3609    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3610            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3611            int startFlags, Configuration config, Bundle options, int userId) {
3612        enforceNotIsolatedCaller("startActivityWithConfig");
3613        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3614                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3615        // TODO: Switch to user app stacks here.
3616        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3617                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3618                null, null, config, options, userId, null, null);
3619        return ret;
3620    }
3621
3622    @Override
3623    public int startActivityIntentSender(IApplicationThread caller,
3624            IntentSender intent, Intent fillInIntent, String resolvedType,
3625            IBinder resultTo, String resultWho, int requestCode,
3626            int flagsMask, int flagsValues, Bundle options) {
3627        enforceNotIsolatedCaller("startActivityIntentSender");
3628        // Refuse possible leaked file descriptors
3629        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3630            throw new IllegalArgumentException("File descriptors passed in Intent");
3631        }
3632
3633        IIntentSender sender = intent.getTarget();
3634        if (!(sender instanceof PendingIntentRecord)) {
3635            throw new IllegalArgumentException("Bad PendingIntent object");
3636        }
3637
3638        PendingIntentRecord pir = (PendingIntentRecord)sender;
3639
3640        synchronized (this) {
3641            // If this is coming from the currently resumed activity, it is
3642            // effectively saying that app switches are allowed at this point.
3643            final ActivityStack stack = getFocusedStack();
3644            if (stack.mResumedActivity != null &&
3645                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3646                mAppSwitchesAllowedTime = 0;
3647            }
3648        }
3649        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3650                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3651        return ret;
3652    }
3653
3654    @Override
3655    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3656            Intent intent, String resolvedType, IVoiceInteractionSession session,
3657            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3658            Bundle options, int userId) {
3659        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3660                != PackageManager.PERMISSION_GRANTED) {
3661            String msg = "Permission Denial: startVoiceActivity() from pid="
3662                    + Binder.getCallingPid()
3663                    + ", uid=" + Binder.getCallingUid()
3664                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3665            Slog.w(TAG, msg);
3666            throw new SecurityException(msg);
3667        }
3668        if (session == null || interactor == null) {
3669            throw new NullPointerException("null session or interactor");
3670        }
3671        userId = handleIncomingUser(callingPid, callingUid, userId,
3672                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3673        // TODO: Switch to user app stacks here.
3674        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3675                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3676                null, options, userId, null, null);
3677    }
3678
3679    @Override
3680    public boolean startNextMatchingActivity(IBinder callingActivity,
3681            Intent intent, Bundle options) {
3682        // Refuse possible leaked file descriptors
3683        if (intent != null && intent.hasFileDescriptors() == true) {
3684            throw new IllegalArgumentException("File descriptors passed in Intent");
3685        }
3686
3687        synchronized (this) {
3688            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3689            if (r == null) {
3690                ActivityOptions.abort(options);
3691                return false;
3692            }
3693            if (r.app == null || r.app.thread == null) {
3694                // The caller is not running...  d'oh!
3695                ActivityOptions.abort(options);
3696                return false;
3697            }
3698            intent = new Intent(intent);
3699            // The caller is not allowed to change the data.
3700            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3701            // And we are resetting to find the next component...
3702            intent.setComponent(null);
3703
3704            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3705
3706            ActivityInfo aInfo = null;
3707            try {
3708                List<ResolveInfo> resolves =
3709                    AppGlobals.getPackageManager().queryIntentActivities(
3710                            intent, r.resolvedType,
3711                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3712                            UserHandle.getCallingUserId());
3713
3714                // Look for the original activity in the list...
3715                final int N = resolves != null ? resolves.size() : 0;
3716                for (int i=0; i<N; i++) {
3717                    ResolveInfo rInfo = resolves.get(i);
3718                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3719                            && rInfo.activityInfo.name.equals(r.info.name)) {
3720                        // We found the current one...  the next matching is
3721                        // after it.
3722                        i++;
3723                        if (i<N) {
3724                            aInfo = resolves.get(i).activityInfo;
3725                        }
3726                        if (debug) {
3727                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3728                                    + "/" + r.info.name);
3729                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3730                                    + "/" + aInfo.name);
3731                        }
3732                        break;
3733                    }
3734                }
3735            } catch (RemoteException e) {
3736            }
3737
3738            if (aInfo == null) {
3739                // Nobody who is next!
3740                ActivityOptions.abort(options);
3741                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3742                return false;
3743            }
3744
3745            intent.setComponent(new ComponentName(
3746                    aInfo.applicationInfo.packageName, aInfo.name));
3747            intent.setFlags(intent.getFlags()&~(
3748                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3749                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3750                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3751                    Intent.FLAG_ACTIVITY_NEW_TASK));
3752
3753            // Okay now we need to start the new activity, replacing the
3754            // currently running activity.  This is a little tricky because
3755            // we want to start the new one as if the current one is finished,
3756            // but not finish the current one first so that there is no flicker.
3757            // And thus...
3758            final boolean wasFinishing = r.finishing;
3759            r.finishing = true;
3760
3761            // Propagate reply information over to the new activity.
3762            final ActivityRecord resultTo = r.resultTo;
3763            final String resultWho = r.resultWho;
3764            final int requestCode = r.requestCode;
3765            r.resultTo = null;
3766            if (resultTo != null) {
3767                resultTo.removeResultsLocked(r, resultWho, requestCode);
3768            }
3769
3770            final long origId = Binder.clearCallingIdentity();
3771            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3772                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3773                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3774                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3775            Binder.restoreCallingIdentity(origId);
3776
3777            r.finishing = wasFinishing;
3778            if (res != ActivityManager.START_SUCCESS) {
3779                return false;
3780            }
3781            return true;
3782        }
3783    }
3784
3785    @Override
3786    public final int startActivityFromRecents(int taskId, Bundle options) {
3787        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3788            String msg = "Permission Denial: startActivityFromRecents called without " +
3789                    START_TASKS_FROM_RECENTS;
3790            Slog.w(TAG, msg);
3791            throw new SecurityException(msg);
3792        }
3793        return startActivityFromRecentsInner(taskId, options);
3794    }
3795
3796    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3797        final TaskRecord task;
3798        final int callingUid;
3799        final String callingPackage;
3800        final Intent intent;
3801        final int userId;
3802        synchronized (this) {
3803            task = recentTaskForIdLocked(taskId);
3804            if (task == null) {
3805                throw new IllegalArgumentException("Task " + taskId + " not found.");
3806            }
3807            callingUid = task.mCallingUid;
3808            callingPackage = task.mCallingPackage;
3809            intent = task.intent;
3810            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3811            userId = task.userId;
3812        }
3813        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3814                options, userId, null, task);
3815    }
3816
3817    final int startActivityInPackage(int uid, String callingPackage,
3818            Intent intent, String resolvedType, IBinder resultTo,
3819            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3820            IActivityContainer container, TaskRecord inTask) {
3821
3822        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3823                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3824
3825        // TODO: Switch to user app stacks here.
3826        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3827                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3828                null, null, null, options, userId, container, inTask);
3829        return ret;
3830    }
3831
3832    @Override
3833    public final int startActivities(IApplicationThread caller, String callingPackage,
3834            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3835            int userId) {
3836        enforceNotIsolatedCaller("startActivities");
3837        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3838                false, ALLOW_FULL_ONLY, "startActivity", null);
3839        // TODO: Switch to user app stacks here.
3840        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3841                resolvedTypes, resultTo, options, userId);
3842        return ret;
3843    }
3844
3845    final int startActivitiesInPackage(int uid, String callingPackage,
3846            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3847            Bundle options, int userId) {
3848
3849        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3850                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3851        // TODO: Switch to user app stacks here.
3852        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3853                resultTo, options, userId);
3854        return ret;
3855    }
3856
3857    //explicitly remove thd old information in mRecentTasks when removing existing user.
3858    private void removeRecentTasksForUserLocked(int userId) {
3859        if(userId <= 0) {
3860            Slog.i(TAG, "Can't remove recent task on user " + userId);
3861            return;
3862        }
3863
3864        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3865            TaskRecord tr = mRecentTasks.get(i);
3866            if (tr.userId == userId) {
3867                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3868                        + " when finishing user" + userId);
3869                mRecentTasks.remove(i);
3870                tr.removedFromRecents(mTaskPersister);
3871            }
3872        }
3873
3874        // Remove tasks from persistent storage.
3875        mTaskPersister.wakeup(null, true);
3876    }
3877
3878    // Sort by taskId
3879    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3880        @Override
3881        public int compare(TaskRecord lhs, TaskRecord rhs) {
3882            return rhs.taskId - lhs.taskId;
3883        }
3884    };
3885
3886    // Extract the affiliates of the chain containing mRecentTasks[start].
3887    private int processNextAffiliateChain(int start) {
3888        final TaskRecord startTask = mRecentTasks.get(start);
3889        final int affiliateId = startTask.mAffiliatedTaskId;
3890
3891        // Quick identification of isolated tasks. I.e. those not launched behind.
3892        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3893                startTask.mNextAffiliate == null) {
3894            // There is still a slim chance that there are other tasks that point to this task
3895            // and that the chain is so messed up that this task no longer points to them but
3896            // the gain of this optimization outweighs the risk.
3897            startTask.inRecents = true;
3898            return start + 1;
3899        }
3900
3901        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3902        mTmpRecents.clear();
3903        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3904            final TaskRecord task = mRecentTasks.get(i);
3905            if (task.mAffiliatedTaskId == affiliateId) {
3906                mRecentTasks.remove(i);
3907                mTmpRecents.add(task);
3908            }
3909        }
3910
3911        // Sort them all by taskId. That is the order they were create in and that order will
3912        // always be correct.
3913        Collections.sort(mTmpRecents, mTaskRecordComparator);
3914
3915        // Go through and fix up the linked list.
3916        // The first one is the end of the chain and has no next.
3917        final TaskRecord first = mTmpRecents.get(0);
3918        first.inRecents = true;
3919        if (first.mNextAffiliate != null) {
3920            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3921            first.setNextAffiliate(null);
3922            mTaskPersister.wakeup(first, false);
3923        }
3924        // Everything in the middle is doubly linked from next to prev.
3925        final int tmpSize = mTmpRecents.size();
3926        for (int i = 0; i < tmpSize - 1; ++i) {
3927            final TaskRecord next = mTmpRecents.get(i);
3928            final TaskRecord prev = mTmpRecents.get(i + 1);
3929            if (next.mPrevAffiliate != prev) {
3930                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3931                        " setting prev=" + prev);
3932                next.setPrevAffiliate(prev);
3933                mTaskPersister.wakeup(next, false);
3934            }
3935            if (prev.mNextAffiliate != next) {
3936                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3937                        " setting next=" + next);
3938                prev.setNextAffiliate(next);
3939                mTaskPersister.wakeup(prev, false);
3940            }
3941            prev.inRecents = true;
3942        }
3943        // The last one is the beginning of the list and has no prev.
3944        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3945        if (last.mPrevAffiliate != null) {
3946            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3947            last.setPrevAffiliate(null);
3948            mTaskPersister.wakeup(last, false);
3949        }
3950
3951        // Insert the group back into mRecentTasks at start.
3952        mRecentTasks.addAll(start, mTmpRecents);
3953
3954        // Let the caller know where we left off.
3955        return start + tmpSize;
3956    }
3957
3958    /**
3959     * Update the recent tasks lists: make sure tasks should still be here (their
3960     * applications / activities still exist), update their availability, fixup ordering
3961     * of affiliations.
3962     */
3963    void cleanupRecentTasksLocked(int userId) {
3964        if (mRecentTasks == null) {
3965            // Happens when called from the packagemanager broadcast before boot.
3966            return;
3967        }
3968
3969        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3970        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3971        final IPackageManager pm = AppGlobals.getPackageManager();
3972        final ActivityInfo dummyAct = new ActivityInfo();
3973        final ApplicationInfo dummyApp = new ApplicationInfo();
3974
3975        int N = mRecentTasks.size();
3976
3977        int[] users = userId == UserHandle.USER_ALL
3978                ? getUsersLocked() : new int[] { userId };
3979        for (int user : users) {
3980            for (int i = 0; i < N; i++) {
3981                TaskRecord task = mRecentTasks.get(i);
3982                if (task.userId != user) {
3983                    // Only look at tasks for the user ID of interest.
3984                    continue;
3985                }
3986                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3987                    // This situation is broken, and we should just get rid of it now.
3988                    mRecentTasks.remove(i);
3989                    task.removedFromRecents(mTaskPersister);
3990                    i--;
3991                    N--;
3992                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3993                    continue;
3994                }
3995                // Check whether this activity is currently available.
3996                if (task.realActivity != null) {
3997                    ActivityInfo ai = availActCache.get(task.realActivity);
3998                    if (ai == null) {
3999                        try {
4000                            ai = pm.getActivityInfo(task.realActivity,
4001                                    PackageManager.GET_UNINSTALLED_PACKAGES
4002                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4003                        } catch (RemoteException e) {
4004                            // Will never happen.
4005                            continue;
4006                        }
4007                        if (ai == null) {
4008                            ai = dummyAct;
4009                        }
4010                        availActCache.put(task.realActivity, ai);
4011                    }
4012                    if (ai == dummyAct) {
4013                        // This could be either because the activity no longer exists, or the
4014                        // app is temporarily gone.  For the former we want to remove the recents
4015                        // entry; for the latter we want to mark it as unavailable.
4016                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4017                        if (app == null) {
4018                            try {
4019                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4020                                        PackageManager.GET_UNINSTALLED_PACKAGES
4021                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4022                            } catch (RemoteException e) {
4023                                // Will never happen.
4024                                continue;
4025                            }
4026                            if (app == null) {
4027                                app = dummyApp;
4028                            }
4029                            availAppCache.put(task.realActivity.getPackageName(), app);
4030                        }
4031                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4032                            // Doesn't exist any more!  Good-bye.
4033                            mRecentTasks.remove(i);
4034                            task.removedFromRecents(mTaskPersister);
4035                            i--;
4036                            N--;
4037                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4038                            continue;
4039                        } else {
4040                            // Otherwise just not available for now.
4041                            if (task.isAvailable) {
4042                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4043                                        + task);
4044                            }
4045                            task.isAvailable = false;
4046                        }
4047                    } else {
4048                        if (!ai.enabled || !ai.applicationInfo.enabled
4049                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4050                            if (task.isAvailable) {
4051                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4052                                        + task + " (enabled=" + ai.enabled + "/"
4053                                        + ai.applicationInfo.enabled +  " flags="
4054                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4055                            }
4056                            task.isAvailable = false;
4057                        } else {
4058                            if (!task.isAvailable) {
4059                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4060                                        + task);
4061                            }
4062                            task.isAvailable = true;
4063                        }
4064                    }
4065                }
4066            }
4067        }
4068
4069        // Verify the affiliate chain for each task.
4070        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4071        }
4072
4073        mTmpRecents.clear();
4074        // mRecentTasks is now in sorted, affiliated order.
4075    }
4076
4077    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4078        int N = mRecentTasks.size();
4079        TaskRecord top = task;
4080        int topIndex = taskIndex;
4081        while (top.mNextAffiliate != null && topIndex > 0) {
4082            top = top.mNextAffiliate;
4083            topIndex--;
4084        }
4085        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4086                + topIndex + " from intial " + taskIndex);
4087        // Find the end of the chain, doing a sanity check along the way.
4088        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4089        int endIndex = topIndex;
4090        TaskRecord prev = top;
4091        while (endIndex < N) {
4092            TaskRecord cur = mRecentTasks.get(endIndex);
4093            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4094                    + endIndex + " " + cur);
4095            if (cur == top) {
4096                // Verify start of the chain.
4097                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4098                    Slog.wtf(TAG, "Bad chain @" + endIndex
4099                            + ": first task has next affiliate: " + prev);
4100                    sane = false;
4101                    break;
4102                }
4103            } else {
4104                // Verify middle of the chain's next points back to the one before.
4105                if (cur.mNextAffiliate != prev
4106                        || cur.mNextAffiliateTaskId != prev.taskId) {
4107                    Slog.wtf(TAG, "Bad chain @" + endIndex
4108                            + ": middle task " + cur + " @" + endIndex
4109                            + " has bad next affiliate "
4110                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4111                            + ", expected " + prev);
4112                    sane = false;
4113                    break;
4114                }
4115            }
4116            if (cur.mPrevAffiliateTaskId == -1) {
4117                // Chain ends here.
4118                if (cur.mPrevAffiliate != null) {
4119                    Slog.wtf(TAG, "Bad chain @" + endIndex
4120                            + ": last task " + cur + " has previous affiliate "
4121                            + cur.mPrevAffiliate);
4122                    sane = false;
4123                }
4124                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4125                break;
4126            } else {
4127                // Verify middle of the chain's prev points to a valid item.
4128                if (cur.mPrevAffiliate == null) {
4129                    Slog.wtf(TAG, "Bad chain @" + endIndex
4130                            + ": task " + cur + " has previous affiliate "
4131                            + cur.mPrevAffiliate + " but should be id "
4132                            + cur.mPrevAffiliate);
4133                    sane = false;
4134                    break;
4135                }
4136            }
4137            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4138                Slog.wtf(TAG, "Bad chain @" + endIndex
4139                        + ": task " + cur + " has affiliated id "
4140                        + cur.mAffiliatedTaskId + " but should be "
4141                        + task.mAffiliatedTaskId);
4142                sane = false;
4143                break;
4144            }
4145            prev = cur;
4146            endIndex++;
4147            if (endIndex >= N) {
4148                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4149                        + ": last task " + prev);
4150                sane = false;
4151                break;
4152            }
4153        }
4154        if (sane) {
4155            if (endIndex < taskIndex) {
4156                Slog.wtf(TAG, "Bad chain @" + endIndex
4157                        + ": did not extend to task " + task + " @" + taskIndex);
4158                sane = false;
4159            }
4160        }
4161        if (sane) {
4162            // All looks good, we can just move all of the affiliated tasks
4163            // to the top.
4164            for (int i=topIndex; i<=endIndex; i++) {
4165                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4166                        + " from " + i + " to " + (i-topIndex));
4167                TaskRecord cur = mRecentTasks.remove(i);
4168                mRecentTasks.add(i-topIndex, cur);
4169            }
4170            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4171                    + " to " + endIndex);
4172            return true;
4173        }
4174
4175        // Whoops, couldn't do it.
4176        return false;
4177    }
4178
4179    final void addRecentTaskLocked(TaskRecord task) {
4180        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4181                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4182
4183        int N = mRecentTasks.size();
4184        // Quick case: check if the top-most recent task is the same.
4185        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4186            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4187            return;
4188        }
4189        // Another quick case: check if this is part of a set of affiliated
4190        // tasks that are at the top.
4191        if (isAffiliated && N > 0 && task.inRecents
4192                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4193            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4194                    + " at top when adding " + task);
4195            return;
4196        }
4197        // Another quick case: never add voice sessions.
4198        if (task.voiceSession != null) {
4199            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4200            return;
4201        }
4202
4203        boolean needAffiliationFix = false;
4204
4205        // Slightly less quick case: the task is already in recents, so all we need
4206        // to do is move it.
4207        if (task.inRecents) {
4208            int taskIndex = mRecentTasks.indexOf(task);
4209            if (taskIndex >= 0) {
4210                if (!isAffiliated) {
4211                    // Simple case: this is not an affiliated task, so we just move it to the front.
4212                    mRecentTasks.remove(taskIndex);
4213                    mRecentTasks.add(0, task);
4214                    notifyTaskPersisterLocked(task, false);
4215                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4216                            + " from " + taskIndex);
4217                    return;
4218                } else {
4219                    // More complicated: need to keep all affiliated tasks together.
4220                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4221                        // All went well.
4222                        return;
4223                    }
4224
4225                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4226                    // everything and then go through our general path of adding a new task.
4227                    needAffiliationFix = true;
4228                }
4229            } else {
4230                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4231                needAffiliationFix = true;
4232            }
4233        }
4234
4235        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4236        trimRecentsForTask(task, true);
4237
4238        N = mRecentTasks.size();
4239        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4240            final TaskRecord tr = mRecentTasks.remove(N - 1);
4241            tr.removedFromRecents(mTaskPersister);
4242            N--;
4243        }
4244        task.inRecents = true;
4245        if (!isAffiliated || needAffiliationFix) {
4246            // If this is a simple non-affiliated task, or we had some failure trying to
4247            // handle it as part of an affilated task, then just place it at the top.
4248            mRecentTasks.add(0, task);
4249        } else if (isAffiliated) {
4250            // If this is a new affiliated task, then move all of the affiliated tasks
4251            // to the front and insert this new one.
4252            TaskRecord other = task.mNextAffiliate;
4253            if (other == null) {
4254                other = task.mPrevAffiliate;
4255            }
4256            if (other != null) {
4257                int otherIndex = mRecentTasks.indexOf(other);
4258                if (otherIndex >= 0) {
4259                    // Insert new task at appropriate location.
4260                    int taskIndex;
4261                    if (other == task.mNextAffiliate) {
4262                        // We found the index of our next affiliation, which is who is
4263                        // before us in the list, so add after that point.
4264                        taskIndex = otherIndex+1;
4265                    } else {
4266                        // We found the index of our previous affiliation, which is who is
4267                        // after us in the list, so add at their position.
4268                        taskIndex = otherIndex;
4269                    }
4270                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4271                            + taskIndex + ": " + task);
4272                    mRecentTasks.add(taskIndex, task);
4273
4274                    // Now move everything to the front.
4275                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4276                        // All went well.
4277                        return;
4278                    }
4279
4280                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4281                    // everything and then go through our general path of adding a new task.
4282                    needAffiliationFix = true;
4283                } else {
4284                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4285                            + other);
4286                    needAffiliationFix = true;
4287                }
4288            } else {
4289                if (DEBUG_RECENTS) Slog.d(TAG,
4290                        "addRecent: adding affiliated task without next/prev:" + task);
4291                needAffiliationFix = true;
4292            }
4293        }
4294        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4295
4296        if (needAffiliationFix) {
4297            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4298            cleanupRecentTasksLocked(task.userId);
4299        }
4300    }
4301
4302    /**
4303     * If needed, remove oldest existing entries in recents that are for the same kind
4304     * of task as the given one.
4305     */
4306    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4307        int N = mRecentTasks.size();
4308        final Intent intent = task.intent;
4309        final boolean document = intent != null && intent.isDocument();
4310
4311        int maxRecents = task.maxRecents - 1;
4312        for (int i=0; i<N; i++) {
4313            final TaskRecord tr = mRecentTasks.get(i);
4314            if (task != tr) {
4315                if (task.userId != tr.userId) {
4316                    continue;
4317                }
4318                if (i > MAX_RECENT_BITMAPS) {
4319                    tr.freeLastThumbnail();
4320                }
4321                final Intent trIntent = tr.intent;
4322                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4323                    (intent == null || !intent.filterEquals(trIntent))) {
4324                    continue;
4325                }
4326                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4327                if (document && trIsDocument) {
4328                    // These are the same document activity (not necessarily the same doc).
4329                    if (maxRecents > 0) {
4330                        --maxRecents;
4331                        continue;
4332                    }
4333                    // Hit the maximum number of documents for this task. Fall through
4334                    // and remove this document from recents.
4335                } else if (document || trIsDocument) {
4336                    // Only one of these is a document. Not the droid we're looking for.
4337                    continue;
4338                }
4339            }
4340
4341            if (!doTrim) {
4342                // If the caller is not actually asking for a trim, just tell them we reached
4343                // a point where the trim would happen.
4344                return i;
4345            }
4346
4347            // Either task and tr are the same or, their affinities match or their intents match
4348            // and neither of them is a document, or they are documents using the same activity
4349            // and their maxRecents has been reached.
4350            tr.disposeThumbnail();
4351            mRecentTasks.remove(i);
4352            if (task != tr) {
4353                tr.removedFromRecents(mTaskPersister);
4354            }
4355            i--;
4356            N--;
4357            if (task.intent == null) {
4358                // If the new recent task we are adding is not fully
4359                // specified, then replace it with the existing recent task.
4360                task = tr;
4361            }
4362            notifyTaskPersisterLocked(tr, false);
4363        }
4364
4365        return -1;
4366    }
4367
4368    @Override
4369    public void reportActivityFullyDrawn(IBinder token) {
4370        synchronized (this) {
4371            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4372            if (r == null) {
4373                return;
4374            }
4375            r.reportFullyDrawnLocked();
4376        }
4377    }
4378
4379    @Override
4380    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4381        synchronized (this) {
4382            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4383            if (r == null) {
4384                return;
4385            }
4386            final long origId = Binder.clearCallingIdentity();
4387            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4388            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4389                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4390            if (config != null) {
4391                r.frozenBeforeDestroy = true;
4392                if (!updateConfigurationLocked(config, r, false, false)) {
4393                    mStackSupervisor.resumeTopActivitiesLocked();
4394                }
4395            }
4396            Binder.restoreCallingIdentity(origId);
4397        }
4398    }
4399
4400    @Override
4401    public int getRequestedOrientation(IBinder token) {
4402        synchronized (this) {
4403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404            if (r == null) {
4405                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4406            }
4407            return mWindowManager.getAppOrientation(r.appToken);
4408        }
4409    }
4410
4411    /**
4412     * This is the internal entry point for handling Activity.finish().
4413     *
4414     * @param token The Binder token referencing the Activity we want to finish.
4415     * @param resultCode Result code, if any, from this Activity.
4416     * @param resultData Result data (Intent), if any, from this Activity.
4417     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4418     *            the root Activity in the task.
4419     *
4420     * @return Returns true if the activity successfully finished, or false if it is still running.
4421     */
4422    @Override
4423    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4424            boolean finishTask) {
4425        // Refuse possible leaked file descriptors
4426        if (resultData != null && resultData.hasFileDescriptors() == true) {
4427            throw new IllegalArgumentException("File descriptors passed in Intent");
4428        }
4429
4430        synchronized(this) {
4431            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4432            if (r == null) {
4433                return true;
4434            }
4435            // Keep track of the root activity of the task before we finish it
4436            TaskRecord tr = r.task;
4437            ActivityRecord rootR = tr.getRootActivity();
4438            // Do not allow task to finish in Lock Task mode.
4439            if (tr == mStackSupervisor.mLockTaskModeTask) {
4440                if (rootR == r) {
4441                    mStackSupervisor.showLockTaskToast();
4442                    return false;
4443                }
4444            }
4445            if (mController != null) {
4446                // Find the first activity that is not finishing.
4447                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4448                if (next != null) {
4449                    // ask watcher if this is allowed
4450                    boolean resumeOK = true;
4451                    try {
4452                        resumeOK = mController.activityResuming(next.packageName);
4453                    } catch (RemoteException e) {
4454                        mController = null;
4455                        Watchdog.getInstance().setActivityController(null);
4456                    }
4457
4458                    if (!resumeOK) {
4459                        return false;
4460                    }
4461                }
4462            }
4463            final long origId = Binder.clearCallingIdentity();
4464            try {
4465                boolean res;
4466                if (finishTask && r == rootR) {
4467                    // If requested, remove the task that is associated to this activity only if it
4468                    // was the root activity in the task.  The result code and data is ignored because
4469                    // we don't support returning them across task boundaries.
4470                    res = removeTaskByIdLocked(tr.taskId, 0);
4471                } else {
4472                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4473                            resultData, "app-request", true);
4474                }
4475                return res;
4476            } finally {
4477                Binder.restoreCallingIdentity(origId);
4478            }
4479        }
4480    }
4481
4482    @Override
4483    public final void finishHeavyWeightApp() {
4484        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4485                != PackageManager.PERMISSION_GRANTED) {
4486            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4487                    + Binder.getCallingPid()
4488                    + ", uid=" + Binder.getCallingUid()
4489                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4490            Slog.w(TAG, msg);
4491            throw new SecurityException(msg);
4492        }
4493
4494        synchronized(this) {
4495            if (mHeavyWeightProcess == null) {
4496                return;
4497            }
4498
4499            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4500                    mHeavyWeightProcess.activities);
4501            for (int i=0; i<activities.size(); i++) {
4502                ActivityRecord r = activities.get(i);
4503                if (!r.finishing) {
4504                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4505                            null, "finish-heavy", true);
4506                }
4507            }
4508
4509            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4510                    mHeavyWeightProcess.userId, 0));
4511            mHeavyWeightProcess = null;
4512        }
4513    }
4514
4515    @Override
4516    public void crashApplication(int uid, int initialPid, String packageName,
4517            String message) {
4518        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4519                != PackageManager.PERMISSION_GRANTED) {
4520            String msg = "Permission Denial: crashApplication() from pid="
4521                    + Binder.getCallingPid()
4522                    + ", uid=" + Binder.getCallingUid()
4523                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4524            Slog.w(TAG, msg);
4525            throw new SecurityException(msg);
4526        }
4527
4528        synchronized(this) {
4529            ProcessRecord proc = null;
4530
4531            // Figure out which process to kill.  We don't trust that initialPid
4532            // still has any relation to current pids, so must scan through the
4533            // list.
4534            synchronized (mPidsSelfLocked) {
4535                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4536                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4537                    if (p.uid != uid) {
4538                        continue;
4539                    }
4540                    if (p.pid == initialPid) {
4541                        proc = p;
4542                        break;
4543                    }
4544                    if (p.pkgList.containsKey(packageName)) {
4545                        proc = p;
4546                    }
4547                }
4548            }
4549
4550            if (proc == null) {
4551                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4552                        + " initialPid=" + initialPid
4553                        + " packageName=" + packageName);
4554                return;
4555            }
4556
4557            if (proc.thread != null) {
4558                if (proc.pid == Process.myPid()) {
4559                    Log.w(TAG, "crashApplication: trying to crash self!");
4560                    return;
4561                }
4562                long ident = Binder.clearCallingIdentity();
4563                try {
4564                    proc.thread.scheduleCrash(message);
4565                } catch (RemoteException e) {
4566                }
4567                Binder.restoreCallingIdentity(ident);
4568            }
4569        }
4570    }
4571
4572    @Override
4573    public final void finishSubActivity(IBinder token, String resultWho,
4574            int requestCode) {
4575        synchronized(this) {
4576            final long origId = Binder.clearCallingIdentity();
4577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4578            if (r != null) {
4579                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4580            }
4581            Binder.restoreCallingIdentity(origId);
4582        }
4583    }
4584
4585    @Override
4586    public boolean finishActivityAffinity(IBinder token) {
4587        synchronized(this) {
4588            final long origId = Binder.clearCallingIdentity();
4589            try {
4590                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4591
4592                ActivityRecord rootR = r.task.getRootActivity();
4593                // Do not allow task to finish in Lock Task mode.
4594                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4595                    if (rootR == r) {
4596                        mStackSupervisor.showLockTaskToast();
4597                        return false;
4598                    }
4599                }
4600                boolean res = false;
4601                if (r != null) {
4602                    res = r.task.stack.finishActivityAffinityLocked(r);
4603                }
4604                return res;
4605            } finally {
4606                Binder.restoreCallingIdentity(origId);
4607            }
4608        }
4609    }
4610
4611    @Override
4612    public void finishVoiceTask(IVoiceInteractionSession session) {
4613        synchronized(this) {
4614            final long origId = Binder.clearCallingIdentity();
4615            try {
4616                mStackSupervisor.finishVoiceTask(session);
4617            } finally {
4618                Binder.restoreCallingIdentity(origId);
4619            }
4620        }
4621
4622    }
4623
4624    @Override
4625    public boolean releaseActivityInstance(IBinder token) {
4626        synchronized(this) {
4627            final long origId = Binder.clearCallingIdentity();
4628            try {
4629                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4630                if (r.task == null || r.task.stack == null) {
4631                    return false;
4632                }
4633                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4634            } finally {
4635                Binder.restoreCallingIdentity(origId);
4636            }
4637        }
4638    }
4639
4640    @Override
4641    public void releaseSomeActivities(IApplicationThread appInt) {
4642        synchronized(this) {
4643            final long origId = Binder.clearCallingIdentity();
4644            try {
4645                ProcessRecord app = getRecordForAppLocked(appInt);
4646                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4647            } finally {
4648                Binder.restoreCallingIdentity(origId);
4649            }
4650        }
4651    }
4652
4653    @Override
4654    public boolean willActivityBeVisible(IBinder token) {
4655        synchronized(this) {
4656            ActivityStack stack = ActivityRecord.getStackLocked(token);
4657            if (stack != null) {
4658                return stack.willActivityBeVisibleLocked(token);
4659            }
4660            return false;
4661        }
4662    }
4663
4664    @Override
4665    public void overridePendingTransition(IBinder token, String packageName,
4666            int enterAnim, int exitAnim) {
4667        synchronized(this) {
4668            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4669            if (self == null) {
4670                return;
4671            }
4672
4673            final long origId = Binder.clearCallingIdentity();
4674
4675            if (self.state == ActivityState.RESUMED
4676                    || self.state == ActivityState.PAUSING) {
4677                mWindowManager.overridePendingAppTransition(packageName,
4678                        enterAnim, exitAnim, null);
4679            }
4680
4681            Binder.restoreCallingIdentity(origId);
4682        }
4683    }
4684
4685    /**
4686     * Main function for removing an existing process from the activity manager
4687     * as a result of that process going away.  Clears out all connections
4688     * to the process.
4689     */
4690    private final void handleAppDiedLocked(ProcessRecord app,
4691            boolean restarting, boolean allowRestart) {
4692        int pid = app.pid;
4693        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4694        if (!kept && !restarting) {
4695            removeLruProcessLocked(app);
4696            if (pid > 0) {
4697                ProcessList.remove(pid);
4698            }
4699        }
4700
4701        if (mProfileProc == app) {
4702            clearProfilerLocked();
4703        }
4704
4705        // Remove this application's activities from active lists.
4706        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4707
4708        app.activities.clear();
4709
4710        if (app.instrumentationClass != null) {
4711            Slog.w(TAG, "Crash of app " + app.processName
4712                  + " running instrumentation " + app.instrumentationClass);
4713            Bundle info = new Bundle();
4714            info.putString("shortMsg", "Process crashed.");
4715            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4716        }
4717
4718        if (!restarting) {
4719            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4720                // If there was nothing to resume, and we are not already
4721                // restarting this process, but there is a visible activity that
4722                // is hosted by the process...  then make sure all visible
4723                // activities are running, taking care of restarting this
4724                // process.
4725                if (hasVisibleActivities) {
4726                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4727                }
4728            }
4729        }
4730    }
4731
4732    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4733        IBinder threadBinder = thread.asBinder();
4734        // Find the application record.
4735        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4736            ProcessRecord rec = mLruProcesses.get(i);
4737            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4738                return i;
4739            }
4740        }
4741        return -1;
4742    }
4743
4744    final ProcessRecord getRecordForAppLocked(
4745            IApplicationThread thread) {
4746        if (thread == null) {
4747            return null;
4748        }
4749
4750        int appIndex = getLRURecordIndexForAppLocked(thread);
4751        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4752    }
4753
4754    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4755        // If there are no longer any background processes running,
4756        // and the app that died was not running instrumentation,
4757        // then tell everyone we are now low on memory.
4758        boolean haveBg = false;
4759        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4760            ProcessRecord rec = mLruProcesses.get(i);
4761            if (rec.thread != null
4762                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4763                haveBg = true;
4764                break;
4765            }
4766        }
4767
4768        if (!haveBg) {
4769            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4770            if (doReport) {
4771                long now = SystemClock.uptimeMillis();
4772                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4773                    doReport = false;
4774                } else {
4775                    mLastMemUsageReportTime = now;
4776                }
4777            }
4778            final ArrayList<ProcessMemInfo> memInfos
4779                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4780            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4781            long now = SystemClock.uptimeMillis();
4782            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4783                ProcessRecord rec = mLruProcesses.get(i);
4784                if (rec == dyingProc || rec.thread == null) {
4785                    continue;
4786                }
4787                if (doReport) {
4788                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4789                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4790                }
4791                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4792                    // The low memory report is overriding any current
4793                    // state for a GC request.  Make sure to do
4794                    // heavy/important/visible/foreground processes first.
4795                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4796                        rec.lastRequestedGc = 0;
4797                    } else {
4798                        rec.lastRequestedGc = rec.lastLowMemory;
4799                    }
4800                    rec.reportLowMemory = true;
4801                    rec.lastLowMemory = now;
4802                    mProcessesToGc.remove(rec);
4803                    addProcessToGcListLocked(rec);
4804                }
4805            }
4806            if (doReport) {
4807                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4808                mHandler.sendMessage(msg);
4809            }
4810            scheduleAppGcsLocked();
4811        }
4812    }
4813
4814    final void appDiedLocked(ProcessRecord app) {
4815       appDiedLocked(app, app.pid, app.thread);
4816    }
4817
4818    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4819        // First check if this ProcessRecord is actually active for the pid.
4820        synchronized (mPidsSelfLocked) {
4821            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4822            if (curProc != app) {
4823                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4824                return;
4825            }
4826        }
4827
4828        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4829        synchronized (stats) {
4830            stats.noteProcessDiedLocked(app.info.uid, pid);
4831        }
4832
4833        Process.killProcessQuiet(pid);
4834        Process.killProcessGroup(app.info.uid, pid);
4835        app.killed = true;
4836
4837        // Clean up already done if the process has been re-started.
4838        if (app.pid == pid && app.thread != null &&
4839                app.thread.asBinder() == thread.asBinder()) {
4840            boolean doLowMem = app.instrumentationClass == null;
4841            boolean doOomAdj = doLowMem;
4842            if (!app.killedByAm) {
4843                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4844                        + ") has died");
4845                mAllowLowerMemLevel = true;
4846            } else {
4847                // Note that we always want to do oom adj to update our state with the
4848                // new number of procs.
4849                mAllowLowerMemLevel = false;
4850                doLowMem = false;
4851            }
4852            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4853            if (DEBUG_CLEANUP) Slog.v(
4854                TAG, "Dying app: " + app + ", pid: " + pid
4855                + ", thread: " + thread.asBinder());
4856            handleAppDiedLocked(app, false, true);
4857
4858            if (doOomAdj) {
4859                updateOomAdjLocked();
4860            }
4861            if (doLowMem) {
4862                doLowMemReportIfNeededLocked(app);
4863            }
4864        } else if (app.pid != pid) {
4865            // A new process has already been started.
4866            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4867                    + ") has died and restarted (pid " + app.pid + ").");
4868            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4869        } else if (DEBUG_PROCESSES) {
4870            Slog.d(TAG, "Received spurious death notification for thread "
4871                    + thread.asBinder());
4872        }
4873    }
4874
4875    /**
4876     * If a stack trace dump file is configured, dump process stack traces.
4877     * @param clearTraces causes the dump file to be erased prior to the new
4878     *    traces being written, if true; when false, the new traces will be
4879     *    appended to any existing file content.
4880     * @param firstPids of dalvik VM processes to dump stack traces for first
4881     * @param lastPids of dalvik VM processes to dump stack traces for last
4882     * @param nativeProcs optional list of native process names to dump stack crawls
4883     * @return file containing stack traces, or null if no dump file is configured
4884     */
4885    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4886            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4887        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4888        if (tracesPath == null || tracesPath.length() == 0) {
4889            return null;
4890        }
4891
4892        File tracesFile = new File(tracesPath);
4893        try {
4894            File tracesDir = tracesFile.getParentFile();
4895            if (!tracesDir.exists()) {
4896                tracesDir.mkdirs();
4897                if (!SELinux.restorecon(tracesDir)) {
4898                    return null;
4899                }
4900            }
4901            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4902
4903            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4904            tracesFile.createNewFile();
4905            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4906        } catch (IOException e) {
4907            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4908            return null;
4909        }
4910
4911        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4912        return tracesFile;
4913    }
4914
4915    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4916            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4917        // Use a FileObserver to detect when traces finish writing.
4918        // The order of traces is considered important to maintain for legibility.
4919        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4920            @Override
4921            public synchronized void onEvent(int event, String path) { notify(); }
4922        };
4923
4924        try {
4925            observer.startWatching();
4926
4927            // First collect all of the stacks of the most important pids.
4928            if (firstPids != null) {
4929                try {
4930                    int num = firstPids.size();
4931                    for (int i = 0; i < num; i++) {
4932                        synchronized (observer) {
4933                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4934                            observer.wait(200);  // Wait for write-close, give up after 200msec
4935                        }
4936                    }
4937                } catch (InterruptedException e) {
4938                    Log.wtf(TAG, e);
4939                }
4940            }
4941
4942            // Next collect the stacks of the native pids
4943            if (nativeProcs != null) {
4944                int[] pids = Process.getPidsForCommands(nativeProcs);
4945                if (pids != null) {
4946                    for (int pid : pids) {
4947                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4948                    }
4949                }
4950            }
4951
4952            // Lastly, measure CPU usage.
4953            if (processCpuTracker != null) {
4954                processCpuTracker.init();
4955                System.gc();
4956                processCpuTracker.update();
4957                try {
4958                    synchronized (processCpuTracker) {
4959                        processCpuTracker.wait(500); // measure over 1/2 second.
4960                    }
4961                } catch (InterruptedException e) {
4962                }
4963                processCpuTracker.update();
4964
4965                // We'll take the stack crawls of just the top apps using CPU.
4966                final int N = processCpuTracker.countWorkingStats();
4967                int numProcs = 0;
4968                for (int i=0; i<N && numProcs<5; i++) {
4969                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4970                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4971                        numProcs++;
4972                        try {
4973                            synchronized (observer) {
4974                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4975                                observer.wait(200);  // Wait for write-close, give up after 200msec
4976                            }
4977                        } catch (InterruptedException e) {
4978                            Log.wtf(TAG, e);
4979                        }
4980
4981                    }
4982                }
4983            }
4984        } finally {
4985            observer.stopWatching();
4986        }
4987    }
4988
4989    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4990        if (true || IS_USER_BUILD) {
4991            return;
4992        }
4993        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4994        if (tracesPath == null || tracesPath.length() == 0) {
4995            return;
4996        }
4997
4998        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4999        StrictMode.allowThreadDiskWrites();
5000        try {
5001            final File tracesFile = new File(tracesPath);
5002            final File tracesDir = tracesFile.getParentFile();
5003            final File tracesTmp = new File(tracesDir, "__tmp__");
5004            try {
5005                if (!tracesDir.exists()) {
5006                    tracesDir.mkdirs();
5007                    if (!SELinux.restorecon(tracesDir.getPath())) {
5008                        return;
5009                    }
5010                }
5011                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5012
5013                if (tracesFile.exists()) {
5014                    tracesTmp.delete();
5015                    tracesFile.renameTo(tracesTmp);
5016                }
5017                StringBuilder sb = new StringBuilder();
5018                Time tobj = new Time();
5019                tobj.set(System.currentTimeMillis());
5020                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5021                sb.append(": ");
5022                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5023                sb.append(" since ");
5024                sb.append(msg);
5025                FileOutputStream fos = new FileOutputStream(tracesFile);
5026                fos.write(sb.toString().getBytes());
5027                if (app == null) {
5028                    fos.write("\n*** No application process!".getBytes());
5029                }
5030                fos.close();
5031                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5032            } catch (IOException e) {
5033                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5034                return;
5035            }
5036
5037            if (app != null) {
5038                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5039                firstPids.add(app.pid);
5040                dumpStackTraces(tracesPath, firstPids, null, null, null);
5041            }
5042
5043            File lastTracesFile = null;
5044            File curTracesFile = null;
5045            for (int i=9; i>=0; i--) {
5046                String name = String.format(Locale.US, "slow%02d.txt", i);
5047                curTracesFile = new File(tracesDir, name);
5048                if (curTracesFile.exists()) {
5049                    if (lastTracesFile != null) {
5050                        curTracesFile.renameTo(lastTracesFile);
5051                    } else {
5052                        curTracesFile.delete();
5053                    }
5054                }
5055                lastTracesFile = curTracesFile;
5056            }
5057            tracesFile.renameTo(curTracesFile);
5058            if (tracesTmp.exists()) {
5059                tracesTmp.renameTo(tracesFile);
5060            }
5061        } finally {
5062            StrictMode.setThreadPolicy(oldPolicy);
5063        }
5064    }
5065
5066    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5067            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5068        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5069        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5070
5071        if (mController != null) {
5072            try {
5073                // 0 == continue, -1 = kill process immediately
5074                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5075                if (res < 0 && app.pid != MY_PID) {
5076                    app.kill("anr", true);
5077                }
5078            } catch (RemoteException e) {
5079                mController = null;
5080                Watchdog.getInstance().setActivityController(null);
5081            }
5082        }
5083
5084        long anrTime = SystemClock.uptimeMillis();
5085        if (MONITOR_CPU_USAGE) {
5086            updateCpuStatsNow();
5087        }
5088
5089        synchronized (this) {
5090            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5091            if (mShuttingDown) {
5092                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5093                return;
5094            } else if (app.notResponding) {
5095                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5096                return;
5097            } else if (app.crashing) {
5098                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5099                return;
5100            }
5101
5102            // In case we come through here for the same app before completing
5103            // this one, mark as anring now so we will bail out.
5104            app.notResponding = true;
5105
5106            // Log the ANR to the event log.
5107            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5108                    app.processName, app.info.flags, annotation);
5109
5110            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5111            firstPids.add(app.pid);
5112
5113            int parentPid = app.pid;
5114            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5115            if (parentPid != app.pid) firstPids.add(parentPid);
5116
5117            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5118
5119            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5120                ProcessRecord r = mLruProcesses.get(i);
5121                if (r != null && r.thread != null) {
5122                    int pid = r.pid;
5123                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5124                        if (r.persistent) {
5125                            firstPids.add(pid);
5126                        } else {
5127                            lastPids.put(pid, Boolean.TRUE);
5128                        }
5129                    }
5130                }
5131            }
5132        }
5133
5134        // Log the ANR to the main log.
5135        StringBuilder info = new StringBuilder();
5136        info.setLength(0);
5137        info.append("ANR in ").append(app.processName);
5138        if (activity != null && activity.shortComponentName != null) {
5139            info.append(" (").append(activity.shortComponentName).append(")");
5140        }
5141        info.append("\n");
5142        info.append("PID: ").append(app.pid).append("\n");
5143        if (annotation != null) {
5144            info.append("Reason: ").append(annotation).append("\n");
5145        }
5146        if (parent != null && parent != activity) {
5147            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5148        }
5149
5150        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5151
5152        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5153                NATIVE_STACKS_OF_INTEREST);
5154
5155        String cpuInfo = null;
5156        if (MONITOR_CPU_USAGE) {
5157            updateCpuStatsNow();
5158            synchronized (mProcessCpuTracker) {
5159                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5160            }
5161            info.append(processCpuTracker.printCurrentLoad());
5162            info.append(cpuInfo);
5163        }
5164
5165        info.append(processCpuTracker.printCurrentState(anrTime));
5166
5167        Slog.e(TAG, info.toString());
5168        if (tracesFile == null) {
5169            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5170            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5171        }
5172
5173        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5174                cpuInfo, tracesFile, null);
5175
5176        if (mController != null) {
5177            try {
5178                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5179                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5180                if (res != 0) {
5181                    if (res < 0 && app.pid != MY_PID) {
5182                        app.kill("anr", true);
5183                    } else {
5184                        synchronized (this) {
5185                            mServices.scheduleServiceTimeoutLocked(app);
5186                        }
5187                    }
5188                    return;
5189                }
5190            } catch (RemoteException e) {
5191                mController = null;
5192                Watchdog.getInstance().setActivityController(null);
5193            }
5194        }
5195
5196        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5197        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5198                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5199
5200        synchronized (this) {
5201            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5202                app.kill("bg anr", true);
5203                return;
5204            }
5205
5206            // Set the app's notResponding state, and look up the errorReportReceiver
5207            makeAppNotRespondingLocked(app,
5208                    activity != null ? activity.shortComponentName : null,
5209                    annotation != null ? "ANR " + annotation : "ANR",
5210                    info.toString());
5211
5212            // Bring up the infamous App Not Responding dialog
5213            Message msg = Message.obtain();
5214            HashMap<String, Object> map = new HashMap<String, Object>();
5215            msg.what = SHOW_NOT_RESPONDING_MSG;
5216            msg.obj = map;
5217            msg.arg1 = aboveSystem ? 1 : 0;
5218            map.put("app", app);
5219            if (activity != null) {
5220                map.put("activity", activity);
5221            }
5222
5223            mHandler.sendMessage(msg);
5224        }
5225    }
5226
5227    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5228        if (!mLaunchWarningShown) {
5229            mLaunchWarningShown = true;
5230            mHandler.post(new Runnable() {
5231                @Override
5232                public void run() {
5233                    synchronized (ActivityManagerService.this) {
5234                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5235                        d.show();
5236                        mHandler.postDelayed(new Runnable() {
5237                            @Override
5238                            public void run() {
5239                                synchronized (ActivityManagerService.this) {
5240                                    d.dismiss();
5241                                    mLaunchWarningShown = false;
5242                                }
5243                            }
5244                        }, 4000);
5245                    }
5246                }
5247            });
5248        }
5249    }
5250
5251    @Override
5252    public boolean clearApplicationUserData(final String packageName,
5253            final IPackageDataObserver observer, int userId) {
5254        enforceNotIsolatedCaller("clearApplicationUserData");
5255        int uid = Binder.getCallingUid();
5256        int pid = Binder.getCallingPid();
5257        userId = handleIncomingUser(pid, uid,
5258                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5259        long callingId = Binder.clearCallingIdentity();
5260        try {
5261            IPackageManager pm = AppGlobals.getPackageManager();
5262            int pkgUid = -1;
5263            synchronized(this) {
5264                try {
5265                    pkgUid = pm.getPackageUid(packageName, userId);
5266                } catch (RemoteException e) {
5267                }
5268                if (pkgUid == -1) {
5269                    Slog.w(TAG, "Invalid packageName: " + packageName);
5270                    if (observer != null) {
5271                        try {
5272                            observer.onRemoveCompleted(packageName, false);
5273                        } catch (RemoteException e) {
5274                            Slog.i(TAG, "Observer no longer exists.");
5275                        }
5276                    }
5277                    return false;
5278                }
5279                if (uid == pkgUid || checkComponentPermission(
5280                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5281                        pid, uid, -1, true)
5282                        == PackageManager.PERMISSION_GRANTED) {
5283                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5284                } else {
5285                    throw new SecurityException("PID " + pid + " does not have permission "
5286                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5287                                    + " of package " + packageName);
5288                }
5289
5290                // Remove all tasks match the cleared application package and user
5291                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5292                    final TaskRecord tr = mRecentTasks.get(i);
5293                    final String taskPackageName =
5294                            tr.getBaseIntent().getComponent().getPackageName();
5295                    if (tr.userId != userId) continue;
5296                    if (!taskPackageName.equals(packageName)) continue;
5297                    removeTaskByIdLocked(tr.taskId, 0);
5298                }
5299            }
5300
5301            try {
5302                // Clear application user data
5303                pm.clearApplicationUserData(packageName, observer, userId);
5304
5305                synchronized(this) {
5306                    // Remove all permissions granted from/to this package
5307                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5308                }
5309
5310                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5311                        Uri.fromParts("package", packageName, null));
5312                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5313                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5314                        null, null, 0, null, null, null, false, false, userId);
5315            } catch (RemoteException e) {
5316            }
5317        } finally {
5318            Binder.restoreCallingIdentity(callingId);
5319        }
5320        return true;
5321    }
5322
5323    @Override
5324    public void killBackgroundProcesses(final String packageName, int userId) {
5325        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5326                != PackageManager.PERMISSION_GRANTED &&
5327                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5328                        != PackageManager.PERMISSION_GRANTED) {
5329            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5330                    + Binder.getCallingPid()
5331                    + ", uid=" + Binder.getCallingUid()
5332                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5333            Slog.w(TAG, msg);
5334            throw new SecurityException(msg);
5335        }
5336
5337        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5338                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5339        long callingId = Binder.clearCallingIdentity();
5340        try {
5341            IPackageManager pm = AppGlobals.getPackageManager();
5342            synchronized(this) {
5343                int appId = -1;
5344                try {
5345                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5346                } catch (RemoteException e) {
5347                }
5348                if (appId == -1) {
5349                    Slog.w(TAG, "Invalid packageName: " + packageName);
5350                    return;
5351                }
5352                killPackageProcessesLocked(packageName, appId, userId,
5353                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5354            }
5355        } finally {
5356            Binder.restoreCallingIdentity(callingId);
5357        }
5358    }
5359
5360    @Override
5361    public void killAllBackgroundProcesses() {
5362        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5363                != PackageManager.PERMISSION_GRANTED) {
5364            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5365                    + Binder.getCallingPid()
5366                    + ", uid=" + Binder.getCallingUid()
5367                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5368            Slog.w(TAG, msg);
5369            throw new SecurityException(msg);
5370        }
5371
5372        long callingId = Binder.clearCallingIdentity();
5373        try {
5374            synchronized(this) {
5375                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5376                final int NP = mProcessNames.getMap().size();
5377                for (int ip=0; ip<NP; ip++) {
5378                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5379                    final int NA = apps.size();
5380                    for (int ia=0; ia<NA; ia++) {
5381                        ProcessRecord app = apps.valueAt(ia);
5382                        if (app.persistent) {
5383                            // we don't kill persistent processes
5384                            continue;
5385                        }
5386                        if (app.removed) {
5387                            procs.add(app);
5388                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5389                            app.removed = true;
5390                            procs.add(app);
5391                        }
5392                    }
5393                }
5394
5395                int N = procs.size();
5396                for (int i=0; i<N; i++) {
5397                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5398                }
5399                mAllowLowerMemLevel = true;
5400                updateOomAdjLocked();
5401                doLowMemReportIfNeededLocked(null);
5402            }
5403        } finally {
5404            Binder.restoreCallingIdentity(callingId);
5405        }
5406    }
5407
5408    @Override
5409    public void forceStopPackage(final String packageName, int userId) {
5410        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5411                != PackageManager.PERMISSION_GRANTED) {
5412            String msg = "Permission Denial: forceStopPackage() from pid="
5413                    + Binder.getCallingPid()
5414                    + ", uid=" + Binder.getCallingUid()
5415                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5416            Slog.w(TAG, msg);
5417            throw new SecurityException(msg);
5418        }
5419        final int callingPid = Binder.getCallingPid();
5420        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5421                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5422        long callingId = Binder.clearCallingIdentity();
5423        try {
5424            IPackageManager pm = AppGlobals.getPackageManager();
5425            synchronized(this) {
5426                int[] users = userId == UserHandle.USER_ALL
5427                        ? getUsersLocked() : new int[] { userId };
5428                for (int user : users) {
5429                    int pkgUid = -1;
5430                    try {
5431                        pkgUid = pm.getPackageUid(packageName, user);
5432                    } catch (RemoteException e) {
5433                    }
5434                    if (pkgUid == -1) {
5435                        Slog.w(TAG, "Invalid packageName: " + packageName);
5436                        continue;
5437                    }
5438                    try {
5439                        pm.setPackageStoppedState(packageName, true, user);
5440                    } catch (RemoteException e) {
5441                    } catch (IllegalArgumentException e) {
5442                        Slog.w(TAG, "Failed trying to unstop package "
5443                                + packageName + ": " + e);
5444                    }
5445                    if (isUserRunningLocked(user, false)) {
5446                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5447                    }
5448                }
5449            }
5450        } finally {
5451            Binder.restoreCallingIdentity(callingId);
5452        }
5453    }
5454
5455    @Override
5456    public void addPackageDependency(String packageName) {
5457        synchronized (this) {
5458            int callingPid = Binder.getCallingPid();
5459            if (callingPid == Process.myPid()) {
5460                //  Yeah, um, no.
5461                Slog.w(TAG, "Can't addPackageDependency on system process");
5462                return;
5463            }
5464            ProcessRecord proc;
5465            synchronized (mPidsSelfLocked) {
5466                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5467            }
5468            if (proc != null) {
5469                if (proc.pkgDeps == null) {
5470                    proc.pkgDeps = new ArraySet<String>(1);
5471                }
5472                proc.pkgDeps.add(packageName);
5473            }
5474        }
5475    }
5476
5477    /*
5478     * The pkg name and app id have to be specified.
5479     */
5480    @Override
5481    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5482        if (pkg == null) {
5483            return;
5484        }
5485        // Make sure the uid is valid.
5486        if (appid < 0) {
5487            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5488            return;
5489        }
5490        int callerUid = Binder.getCallingUid();
5491        // Only the system server can kill an application
5492        if (callerUid == Process.SYSTEM_UID) {
5493            // Post an aysnc message to kill the application
5494            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5495            msg.arg1 = appid;
5496            msg.arg2 = 0;
5497            Bundle bundle = new Bundle();
5498            bundle.putString("pkg", pkg);
5499            bundle.putString("reason", reason);
5500            msg.obj = bundle;
5501            mHandler.sendMessage(msg);
5502        } else {
5503            throw new SecurityException(callerUid + " cannot kill pkg: " +
5504                    pkg);
5505        }
5506    }
5507
5508    @Override
5509    public void closeSystemDialogs(String reason) {
5510        enforceNotIsolatedCaller("closeSystemDialogs");
5511
5512        final int pid = Binder.getCallingPid();
5513        final int uid = Binder.getCallingUid();
5514        final long origId = Binder.clearCallingIdentity();
5515        try {
5516            synchronized (this) {
5517                // Only allow this from foreground processes, so that background
5518                // applications can't abuse it to prevent system UI from being shown.
5519                if (uid >= Process.FIRST_APPLICATION_UID) {
5520                    ProcessRecord proc;
5521                    synchronized (mPidsSelfLocked) {
5522                        proc = mPidsSelfLocked.get(pid);
5523                    }
5524                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5525                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5526                                + " from background process " + proc);
5527                        return;
5528                    }
5529                }
5530                closeSystemDialogsLocked(reason);
5531            }
5532        } finally {
5533            Binder.restoreCallingIdentity(origId);
5534        }
5535    }
5536
5537    void closeSystemDialogsLocked(String reason) {
5538        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5539        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5540                | Intent.FLAG_RECEIVER_FOREGROUND);
5541        if (reason != null) {
5542            intent.putExtra("reason", reason);
5543        }
5544        mWindowManager.closeSystemDialogs(reason);
5545
5546        mStackSupervisor.closeSystemDialogsLocked();
5547
5548        broadcastIntentLocked(null, null, intent, null,
5549                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5550                Process.SYSTEM_UID, UserHandle.USER_ALL);
5551    }
5552
5553    @Override
5554    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5555        enforceNotIsolatedCaller("getProcessMemoryInfo");
5556        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5557        for (int i=pids.length-1; i>=0; i--) {
5558            ProcessRecord proc;
5559            int oomAdj;
5560            synchronized (this) {
5561                synchronized (mPidsSelfLocked) {
5562                    proc = mPidsSelfLocked.get(pids[i]);
5563                    oomAdj = proc != null ? proc.setAdj : 0;
5564                }
5565            }
5566            infos[i] = new Debug.MemoryInfo();
5567            Debug.getMemoryInfo(pids[i], infos[i]);
5568            if (proc != null) {
5569                synchronized (this) {
5570                    if (proc.thread != null && proc.setAdj == oomAdj) {
5571                        // Record this for posterity if the process has been stable.
5572                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5573                                infos[i].getTotalUss(), false, proc.pkgList);
5574                    }
5575                }
5576            }
5577        }
5578        return infos;
5579    }
5580
5581    @Override
5582    public long[] getProcessPss(int[] pids) {
5583        enforceNotIsolatedCaller("getProcessPss");
5584        long[] pss = new long[pids.length];
5585        for (int i=pids.length-1; i>=0; i--) {
5586            ProcessRecord proc;
5587            int oomAdj;
5588            synchronized (this) {
5589                synchronized (mPidsSelfLocked) {
5590                    proc = mPidsSelfLocked.get(pids[i]);
5591                    oomAdj = proc != null ? proc.setAdj : 0;
5592                }
5593            }
5594            long[] tmpUss = new long[1];
5595            pss[i] = Debug.getPss(pids[i], tmpUss);
5596            if (proc != null) {
5597                synchronized (this) {
5598                    if (proc.thread != null && proc.setAdj == oomAdj) {
5599                        // Record this for posterity if the process has been stable.
5600                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5601                    }
5602                }
5603            }
5604        }
5605        return pss;
5606    }
5607
5608    @Override
5609    public void killApplicationProcess(String processName, int uid) {
5610        if (processName == null) {
5611            return;
5612        }
5613
5614        int callerUid = Binder.getCallingUid();
5615        // Only the system server can kill an application
5616        if (callerUid == Process.SYSTEM_UID) {
5617            synchronized (this) {
5618                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5619                if (app != null && app.thread != null) {
5620                    try {
5621                        app.thread.scheduleSuicide();
5622                    } catch (RemoteException e) {
5623                        // If the other end already died, then our work here is done.
5624                    }
5625                } else {
5626                    Slog.w(TAG, "Process/uid not found attempting kill of "
5627                            + processName + " / " + uid);
5628                }
5629            }
5630        } else {
5631            throw new SecurityException(callerUid + " cannot kill app process: " +
5632                    processName);
5633        }
5634    }
5635
5636    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5637        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5638                false, true, false, false, UserHandle.getUserId(uid), reason);
5639        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5640                Uri.fromParts("package", packageName, null));
5641        if (!mProcessesReady) {
5642            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5643                    | Intent.FLAG_RECEIVER_FOREGROUND);
5644        }
5645        intent.putExtra(Intent.EXTRA_UID, uid);
5646        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5647        broadcastIntentLocked(null, null, intent,
5648                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5649                false, false,
5650                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5651    }
5652
5653    private void forceStopUserLocked(int userId, String reason) {
5654        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5655        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5656        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5657                | Intent.FLAG_RECEIVER_FOREGROUND);
5658        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5659        broadcastIntentLocked(null, null, intent,
5660                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5661                false, false,
5662                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5663    }
5664
5665    private final boolean killPackageProcessesLocked(String packageName, int appId,
5666            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5667            boolean doit, boolean evenPersistent, String reason) {
5668        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5669
5670        // Remove all processes this package may have touched: all with the
5671        // same UID (except for the system or root user), and all whose name
5672        // matches the package name.
5673        final int NP = mProcessNames.getMap().size();
5674        for (int ip=0; ip<NP; ip++) {
5675            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5676            final int NA = apps.size();
5677            for (int ia=0; ia<NA; ia++) {
5678                ProcessRecord app = apps.valueAt(ia);
5679                if (app.persistent && !evenPersistent) {
5680                    // we don't kill persistent processes
5681                    continue;
5682                }
5683                if (app.removed) {
5684                    if (doit) {
5685                        procs.add(app);
5686                    }
5687                    continue;
5688                }
5689
5690                // Skip process if it doesn't meet our oom adj requirement.
5691                if (app.setAdj < minOomAdj) {
5692                    continue;
5693                }
5694
5695                // If no package is specified, we call all processes under the
5696                // give user id.
5697                if (packageName == null) {
5698                    if (app.userId != userId) {
5699                        continue;
5700                    }
5701                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5702                        continue;
5703                    }
5704                // Package has been specified, we want to hit all processes
5705                // that match it.  We need to qualify this by the processes
5706                // that are running under the specified app and user ID.
5707                } else {
5708                    final boolean isDep = app.pkgDeps != null
5709                            && app.pkgDeps.contains(packageName);
5710                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5711                        continue;
5712                    }
5713                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5714                        continue;
5715                    }
5716                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5717                        continue;
5718                    }
5719                }
5720
5721                // Process has passed all conditions, kill it!
5722                if (!doit) {
5723                    return true;
5724                }
5725                app.removed = true;
5726                procs.add(app);
5727            }
5728        }
5729
5730        int N = procs.size();
5731        for (int i=0; i<N; i++) {
5732            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5733        }
5734        updateOomAdjLocked();
5735        return N > 0;
5736    }
5737
5738    private final boolean forceStopPackageLocked(String name, int appId,
5739            boolean callerWillRestart, boolean purgeCache, boolean doit,
5740            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5741        int i;
5742        int N;
5743
5744        if (userId == UserHandle.USER_ALL && name == null) {
5745            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5746        }
5747
5748        if (appId < 0 && name != null) {
5749            try {
5750                appId = UserHandle.getAppId(
5751                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5752            } catch (RemoteException e) {
5753            }
5754        }
5755
5756        if (doit) {
5757            if (name != null) {
5758                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5759                        + " user=" + userId + ": " + reason);
5760            } else {
5761                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5762            }
5763
5764            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5765            for (int ip=pmap.size()-1; ip>=0; ip--) {
5766                SparseArray<Long> ba = pmap.valueAt(ip);
5767                for (i=ba.size()-1; i>=0; i--) {
5768                    boolean remove = false;
5769                    final int entUid = ba.keyAt(i);
5770                    if (name != null) {
5771                        if (userId == UserHandle.USER_ALL) {
5772                            if (UserHandle.getAppId(entUid) == appId) {
5773                                remove = true;
5774                            }
5775                        } else {
5776                            if (entUid == UserHandle.getUid(userId, appId)) {
5777                                remove = true;
5778                            }
5779                        }
5780                    } else if (UserHandle.getUserId(entUid) == userId) {
5781                        remove = true;
5782                    }
5783                    if (remove) {
5784                        ba.removeAt(i);
5785                    }
5786                }
5787                if (ba.size() == 0) {
5788                    pmap.removeAt(ip);
5789                }
5790            }
5791        }
5792
5793        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5794                -100, callerWillRestart, true, doit, evenPersistent,
5795                name == null ? ("stop user " + userId) : ("stop " + name));
5796
5797        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5798            if (!doit) {
5799                return true;
5800            }
5801            didSomething = true;
5802        }
5803
5804        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5805            if (!doit) {
5806                return true;
5807            }
5808            didSomething = true;
5809        }
5810
5811        if (name == null) {
5812            // Remove all sticky broadcasts from this user.
5813            mStickyBroadcasts.remove(userId);
5814        }
5815
5816        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5817        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5818                userId, providers)) {
5819            if (!doit) {
5820                return true;
5821            }
5822            didSomething = true;
5823        }
5824        N = providers.size();
5825        for (i=0; i<N; i++) {
5826            removeDyingProviderLocked(null, providers.get(i), true);
5827        }
5828
5829        // Remove transient permissions granted from/to this package/user
5830        removeUriPermissionsForPackageLocked(name, userId, false);
5831
5832        if (name == null || uninstalling) {
5833            // Remove pending intents.  For now we only do this when force
5834            // stopping users, because we have some problems when doing this
5835            // for packages -- app widgets are not currently cleaned up for
5836            // such packages, so they can be left with bad pending intents.
5837            if (mIntentSenderRecords.size() > 0) {
5838                Iterator<WeakReference<PendingIntentRecord>> it
5839                        = mIntentSenderRecords.values().iterator();
5840                while (it.hasNext()) {
5841                    WeakReference<PendingIntentRecord> wpir = it.next();
5842                    if (wpir == null) {
5843                        it.remove();
5844                        continue;
5845                    }
5846                    PendingIntentRecord pir = wpir.get();
5847                    if (pir == null) {
5848                        it.remove();
5849                        continue;
5850                    }
5851                    if (name == null) {
5852                        // Stopping user, remove all objects for the user.
5853                        if (pir.key.userId != userId) {
5854                            // Not the same user, skip it.
5855                            continue;
5856                        }
5857                    } else {
5858                        if (UserHandle.getAppId(pir.uid) != appId) {
5859                            // Different app id, skip it.
5860                            continue;
5861                        }
5862                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5863                            // Different user, skip it.
5864                            continue;
5865                        }
5866                        if (!pir.key.packageName.equals(name)) {
5867                            // Different package, skip it.
5868                            continue;
5869                        }
5870                    }
5871                    if (!doit) {
5872                        return true;
5873                    }
5874                    didSomething = true;
5875                    it.remove();
5876                    pir.canceled = true;
5877                    if (pir.key.activity != null) {
5878                        pir.key.activity.pendingResults.remove(pir.ref);
5879                    }
5880                }
5881            }
5882        }
5883
5884        if (doit) {
5885            if (purgeCache && name != null) {
5886                AttributeCache ac = AttributeCache.instance();
5887                if (ac != null) {
5888                    ac.removePackage(name);
5889                }
5890            }
5891            if (mBooted) {
5892                mStackSupervisor.resumeTopActivitiesLocked();
5893                mStackSupervisor.scheduleIdleLocked();
5894            }
5895        }
5896
5897        return didSomething;
5898    }
5899
5900    private final boolean removeProcessLocked(ProcessRecord app,
5901            boolean callerWillRestart, boolean allowRestart, String reason) {
5902        final String name = app.processName;
5903        final int uid = app.uid;
5904        if (DEBUG_PROCESSES) Slog.d(
5905            TAG, "Force removing proc " + app.toShortString() + " (" + name
5906            + "/" + uid + ")");
5907
5908        mProcessNames.remove(name, uid);
5909        mIsolatedProcesses.remove(app.uid);
5910        if (mHeavyWeightProcess == app) {
5911            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5912                    mHeavyWeightProcess.userId, 0));
5913            mHeavyWeightProcess = null;
5914        }
5915        boolean needRestart = false;
5916        if (app.pid > 0 && app.pid != MY_PID) {
5917            int pid = app.pid;
5918            synchronized (mPidsSelfLocked) {
5919                mPidsSelfLocked.remove(pid);
5920                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5921            }
5922            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5923            if (app.isolated) {
5924                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5925            }
5926            app.kill(reason, true);
5927            handleAppDiedLocked(app, true, allowRestart);
5928            removeLruProcessLocked(app);
5929
5930            if (app.persistent && !app.isolated) {
5931                if (!callerWillRestart) {
5932                    addAppLocked(app.info, false, null /* ABI override */);
5933                } else {
5934                    needRestart = true;
5935                }
5936            }
5937        } else {
5938            mRemovedProcesses.add(app);
5939        }
5940
5941        return needRestart;
5942    }
5943
5944    private final void processStartTimedOutLocked(ProcessRecord app) {
5945        final int pid = app.pid;
5946        boolean gone = false;
5947        synchronized (mPidsSelfLocked) {
5948            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5949            if (knownApp != null && knownApp.thread == null) {
5950                mPidsSelfLocked.remove(pid);
5951                gone = true;
5952            }
5953        }
5954
5955        if (gone) {
5956            Slog.w(TAG, "Process " + app + " failed to attach");
5957            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5958                    pid, app.uid, app.processName);
5959            mProcessNames.remove(app.processName, app.uid);
5960            mIsolatedProcesses.remove(app.uid);
5961            if (mHeavyWeightProcess == app) {
5962                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5963                        mHeavyWeightProcess.userId, 0));
5964                mHeavyWeightProcess = null;
5965            }
5966            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5967            if (app.isolated) {
5968                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5969            }
5970            // Take care of any launching providers waiting for this process.
5971            checkAppInLaunchingProvidersLocked(app, true);
5972            // Take care of any services that are waiting for the process.
5973            mServices.processStartTimedOutLocked(app);
5974            app.kill("start timeout", true);
5975            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5976                Slog.w(TAG, "Unattached app died before backup, skipping");
5977                try {
5978                    IBackupManager bm = IBackupManager.Stub.asInterface(
5979                            ServiceManager.getService(Context.BACKUP_SERVICE));
5980                    bm.agentDisconnected(app.info.packageName);
5981                } catch (RemoteException e) {
5982                    // Can't happen; the backup manager is local
5983                }
5984            }
5985            if (isPendingBroadcastProcessLocked(pid)) {
5986                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5987                skipPendingBroadcastLocked(pid);
5988            }
5989        } else {
5990            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5991        }
5992    }
5993
5994    private final boolean attachApplicationLocked(IApplicationThread thread,
5995            int pid) {
5996
5997        // Find the application record that is being attached...  either via
5998        // the pid if we are running in multiple processes, or just pull the
5999        // next app record if we are emulating process with anonymous threads.
6000        ProcessRecord app;
6001        if (pid != MY_PID && pid >= 0) {
6002            synchronized (mPidsSelfLocked) {
6003                app = mPidsSelfLocked.get(pid);
6004            }
6005        } else {
6006            app = null;
6007        }
6008
6009        if (app == null) {
6010            Slog.w(TAG, "No pending application record for pid " + pid
6011                    + " (IApplicationThread " + thread + "); dropping process");
6012            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6013            if (pid > 0 && pid != MY_PID) {
6014                Process.killProcessQuiet(pid);
6015                //TODO: Process.killProcessGroup(app.info.uid, pid);
6016            } else {
6017                try {
6018                    thread.scheduleExit();
6019                } catch (Exception e) {
6020                    // Ignore exceptions.
6021                }
6022            }
6023            return false;
6024        }
6025
6026        // If this application record is still attached to a previous
6027        // process, clean it up now.
6028        if (app.thread != null) {
6029            handleAppDiedLocked(app, true, true);
6030        }
6031
6032        // Tell the process all about itself.
6033
6034        if (localLOGV) Slog.v(
6035                TAG, "Binding process pid " + pid + " to record " + app);
6036
6037        final String processName = app.processName;
6038        try {
6039            AppDeathRecipient adr = new AppDeathRecipient(
6040                    app, pid, thread);
6041            thread.asBinder().linkToDeath(adr, 0);
6042            app.deathRecipient = adr;
6043        } catch (RemoteException e) {
6044            app.resetPackageList(mProcessStats);
6045            startProcessLocked(app, "link fail", processName);
6046            return false;
6047        }
6048
6049        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6050
6051        app.makeActive(thread, mProcessStats);
6052        app.curAdj = app.setAdj = -100;
6053        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6054        app.forcingToForeground = null;
6055        updateProcessForegroundLocked(app, false, false);
6056        app.hasShownUi = false;
6057        app.debugging = false;
6058        app.cached = false;
6059
6060        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6061
6062        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6063        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6064
6065        if (!normalMode) {
6066            Slog.i(TAG, "Launching preboot mode app: " + app);
6067        }
6068
6069        if (localLOGV) Slog.v(
6070            TAG, "New app record " + app
6071            + " thread=" + thread.asBinder() + " pid=" + pid);
6072        try {
6073            int testMode = IApplicationThread.DEBUG_OFF;
6074            if (mDebugApp != null && mDebugApp.equals(processName)) {
6075                testMode = mWaitForDebugger
6076                    ? IApplicationThread.DEBUG_WAIT
6077                    : IApplicationThread.DEBUG_ON;
6078                app.debugging = true;
6079                if (mDebugTransient) {
6080                    mDebugApp = mOrigDebugApp;
6081                    mWaitForDebugger = mOrigWaitForDebugger;
6082                }
6083            }
6084            String profileFile = app.instrumentationProfileFile;
6085            ParcelFileDescriptor profileFd = null;
6086            int samplingInterval = 0;
6087            boolean profileAutoStop = false;
6088            if (mProfileApp != null && mProfileApp.equals(processName)) {
6089                mProfileProc = app;
6090                profileFile = mProfileFile;
6091                profileFd = mProfileFd;
6092                samplingInterval = mSamplingInterval;
6093                profileAutoStop = mAutoStopProfiler;
6094            }
6095            boolean enableOpenGlTrace = false;
6096            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6097                enableOpenGlTrace = true;
6098                mOpenGlTraceApp = null;
6099            }
6100
6101            // If the app is being launched for restore or full backup, set it up specially
6102            boolean isRestrictedBackupMode = false;
6103            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6104                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6105                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6106                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6107            }
6108
6109            ensurePackageDexOpt(app.instrumentationInfo != null
6110                    ? app.instrumentationInfo.packageName
6111                    : app.info.packageName);
6112            if (app.instrumentationClass != null) {
6113                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6114            }
6115            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6116                    + processName + " with config " + mConfiguration);
6117            ApplicationInfo appInfo = app.instrumentationInfo != null
6118                    ? app.instrumentationInfo : app.info;
6119            app.compat = compatibilityInfoForPackageLocked(appInfo);
6120            if (profileFd != null) {
6121                profileFd = profileFd.dup();
6122            }
6123            ProfilerInfo profilerInfo = profileFile == null ? null
6124                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6125            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6126                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6127                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6128                    isRestrictedBackupMode || !normalMode, app.persistent,
6129                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6130                    mCoreSettingsObserver.getCoreSettingsLocked());
6131            updateLruProcessLocked(app, false, null);
6132            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6133        } catch (Exception e) {
6134            // todo: Yikes!  What should we do?  For now we will try to
6135            // start another process, but that could easily get us in
6136            // an infinite loop of restarting processes...
6137            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6138
6139            app.resetPackageList(mProcessStats);
6140            app.unlinkDeathRecipient();
6141            startProcessLocked(app, "bind fail", processName);
6142            return false;
6143        }
6144
6145        // Remove this record from the list of starting applications.
6146        mPersistentStartingProcesses.remove(app);
6147        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6148                "Attach application locked removing on hold: " + app);
6149        mProcessesOnHold.remove(app);
6150
6151        boolean badApp = false;
6152        boolean didSomething = false;
6153
6154        // See if the top visible activity is waiting to run in this process...
6155        if (normalMode) {
6156            try {
6157                if (mStackSupervisor.attachApplicationLocked(app)) {
6158                    didSomething = true;
6159                }
6160            } catch (Exception e) {
6161                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6162                badApp = true;
6163            }
6164        }
6165
6166        // Find any services that should be running in this process...
6167        if (!badApp) {
6168            try {
6169                didSomething |= mServices.attachApplicationLocked(app, processName);
6170            } catch (Exception e) {
6171                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6172                badApp = true;
6173            }
6174        }
6175
6176        // Check if a next-broadcast receiver is in this process...
6177        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6178            try {
6179                didSomething |= sendPendingBroadcastsLocked(app);
6180            } catch (Exception e) {
6181                // If the app died trying to launch the receiver we declare it 'bad'
6182                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6183                badApp = true;
6184            }
6185        }
6186
6187        // Check whether the next backup agent is in this process...
6188        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6189            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6190            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6191            try {
6192                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6193                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6194                        mBackupTarget.backupMode);
6195            } catch (Exception e) {
6196                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6197                badApp = true;
6198            }
6199        }
6200
6201        if (badApp) {
6202            app.kill("error during init", true);
6203            handleAppDiedLocked(app, false, true);
6204            return false;
6205        }
6206
6207        if (!didSomething) {
6208            updateOomAdjLocked();
6209        }
6210
6211        return true;
6212    }
6213
6214    @Override
6215    public final void attachApplication(IApplicationThread thread) {
6216        synchronized (this) {
6217            int callingPid = Binder.getCallingPid();
6218            final long origId = Binder.clearCallingIdentity();
6219            attachApplicationLocked(thread, callingPid);
6220            Binder.restoreCallingIdentity(origId);
6221        }
6222    }
6223
6224    @Override
6225    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6226        final long origId = Binder.clearCallingIdentity();
6227        synchronized (this) {
6228            ActivityStack stack = ActivityRecord.getStackLocked(token);
6229            if (stack != null) {
6230                ActivityRecord r =
6231                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6232                if (stopProfiling) {
6233                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6234                        try {
6235                            mProfileFd.close();
6236                        } catch (IOException e) {
6237                        }
6238                        clearProfilerLocked();
6239                    }
6240                }
6241            }
6242        }
6243        Binder.restoreCallingIdentity(origId);
6244    }
6245
6246    void postEnableScreenAfterBootLocked() {
6247        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6248    }
6249
6250    void enableScreenAfterBoot() {
6251        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6252                SystemClock.uptimeMillis());
6253        mWindowManager.enableScreenAfterBoot();
6254
6255        synchronized (this) {
6256            updateEventDispatchingLocked();
6257        }
6258    }
6259
6260    @Override
6261    public void showBootMessage(final CharSequence msg, final boolean always) {
6262        enforceNotIsolatedCaller("showBootMessage");
6263        mWindowManager.showBootMessage(msg, always);
6264    }
6265
6266    @Override
6267    public void keyguardWaitingForActivityDrawn() {
6268        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6269        final long token = Binder.clearCallingIdentity();
6270        try {
6271            synchronized (this) {
6272                if (DEBUG_LOCKSCREEN) logLockScreen("");
6273                mWindowManager.keyguardWaitingForActivityDrawn();
6274                if (mLockScreenShown) {
6275                    mLockScreenShown = false;
6276                    comeOutOfSleepIfNeededLocked();
6277                }
6278            }
6279        } finally {
6280            Binder.restoreCallingIdentity(token);
6281        }
6282    }
6283
6284    final void finishBooting() {
6285        synchronized (this) {
6286            if (!mBootAnimationComplete) {
6287                mCallFinishBooting = true;
6288                return;
6289            }
6290            mCallFinishBooting = false;
6291        }
6292
6293        // Register receivers to handle package update events
6294        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6295
6296        // Let system services know.
6297        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6298
6299        synchronized (this) {
6300            // Ensure that any processes we had put on hold are now started
6301            // up.
6302            final int NP = mProcessesOnHold.size();
6303            if (NP > 0) {
6304                ArrayList<ProcessRecord> procs =
6305                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6306                for (int ip=0; ip<NP; ip++) {
6307                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6308                            + procs.get(ip));
6309                    startProcessLocked(procs.get(ip), "on-hold", null);
6310                }
6311            }
6312
6313            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6314                // Start looking for apps that are abusing wake locks.
6315                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6316                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6317                // Tell anyone interested that we are done booting!
6318                SystemProperties.set("sys.boot_completed", "1");
6319
6320                // And trigger dev.bootcomplete if we are not showing encryption progress
6321                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6322                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6323                    SystemProperties.set("dev.bootcomplete", "1");
6324                }
6325                for (int i=0; i<mStartedUsers.size(); i++) {
6326                    UserStartedState uss = mStartedUsers.valueAt(i);
6327                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6328                        uss.mState = UserStartedState.STATE_RUNNING;
6329                        final int userId = mStartedUsers.keyAt(i);
6330                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6331                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6332                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6333                        broadcastIntentLocked(null, null, intent, null,
6334                                new IIntentReceiver.Stub() {
6335                                    @Override
6336                                    public void performReceive(Intent intent, int resultCode,
6337                                            String data, Bundle extras, boolean ordered,
6338                                            boolean sticky, int sendingUser) {
6339                                        synchronized (ActivityManagerService.this) {
6340                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6341                                                    true, false);
6342                                        }
6343                                    }
6344                                },
6345                                0, null, null,
6346                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6347                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6348                                userId);
6349                    }
6350                }
6351                scheduleStartProfilesLocked();
6352            }
6353        }
6354    }
6355
6356    @Override
6357    public void bootAnimationComplete() {
6358        final boolean callFinishBooting;
6359        synchronized (this) {
6360            callFinishBooting = mCallFinishBooting;
6361            mBootAnimationComplete = true;
6362        }
6363        if (callFinishBooting) {
6364            finishBooting();
6365        }
6366    }
6367
6368    final void ensureBootCompleted() {
6369        boolean booting;
6370        boolean enableScreen;
6371        synchronized (this) {
6372            booting = mBooting;
6373            mBooting = false;
6374            enableScreen = !mBooted;
6375            mBooted = true;
6376        }
6377
6378        if (booting) {
6379            finishBooting();
6380        }
6381
6382        if (enableScreen) {
6383            enableScreenAfterBoot();
6384        }
6385    }
6386
6387    @Override
6388    public final void activityResumed(IBinder token) {
6389        final long origId = Binder.clearCallingIdentity();
6390        synchronized(this) {
6391            ActivityStack stack = ActivityRecord.getStackLocked(token);
6392            if (stack != null) {
6393                ActivityRecord.activityResumedLocked(token);
6394            }
6395        }
6396        Binder.restoreCallingIdentity(origId);
6397    }
6398
6399    @Override
6400    public final void activityPaused(IBinder token) {
6401        final long origId = Binder.clearCallingIdentity();
6402        synchronized(this) {
6403            ActivityStack stack = ActivityRecord.getStackLocked(token);
6404            if (stack != null) {
6405                stack.activityPausedLocked(token, false);
6406            }
6407        }
6408        Binder.restoreCallingIdentity(origId);
6409    }
6410
6411    @Override
6412    public final void activityStopped(IBinder token, Bundle icicle,
6413            PersistableBundle persistentState, CharSequence description) {
6414        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6415
6416        // Refuse possible leaked file descriptors
6417        if (icicle != null && icicle.hasFileDescriptors()) {
6418            throw new IllegalArgumentException("File descriptors passed in Bundle");
6419        }
6420
6421        final long origId = Binder.clearCallingIdentity();
6422
6423        synchronized (this) {
6424            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6425            if (r != null) {
6426                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6427            }
6428        }
6429
6430        trimApplications();
6431
6432        Binder.restoreCallingIdentity(origId);
6433    }
6434
6435    @Override
6436    public final void activityDestroyed(IBinder token) {
6437        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6438        synchronized (this) {
6439            ActivityStack stack = ActivityRecord.getStackLocked(token);
6440            if (stack != null) {
6441                stack.activityDestroyedLocked(token);
6442            }
6443        }
6444    }
6445
6446    @Override
6447    public final void backgroundResourcesReleased(IBinder token) {
6448        final long origId = Binder.clearCallingIdentity();
6449        try {
6450            synchronized (this) {
6451                ActivityStack stack = ActivityRecord.getStackLocked(token);
6452                if (stack != null) {
6453                    stack.backgroundResourcesReleased(token);
6454                }
6455            }
6456        } finally {
6457            Binder.restoreCallingIdentity(origId);
6458        }
6459    }
6460
6461    @Override
6462    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6463        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6464    }
6465
6466    @Override
6467    public final void notifyEnterAnimationComplete(IBinder token) {
6468        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6469    }
6470
6471    @Override
6472    public String getCallingPackage(IBinder token) {
6473        synchronized (this) {
6474            ActivityRecord r = getCallingRecordLocked(token);
6475            return r != null ? r.info.packageName : null;
6476        }
6477    }
6478
6479    @Override
6480    public ComponentName getCallingActivity(IBinder token) {
6481        synchronized (this) {
6482            ActivityRecord r = getCallingRecordLocked(token);
6483            return r != null ? r.intent.getComponent() : null;
6484        }
6485    }
6486
6487    private ActivityRecord getCallingRecordLocked(IBinder token) {
6488        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6489        if (r == null) {
6490            return null;
6491        }
6492        return r.resultTo;
6493    }
6494
6495    @Override
6496    public ComponentName getActivityClassForToken(IBinder token) {
6497        synchronized(this) {
6498            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6499            if (r == null) {
6500                return null;
6501            }
6502            return r.intent.getComponent();
6503        }
6504    }
6505
6506    @Override
6507    public String getPackageForToken(IBinder token) {
6508        synchronized(this) {
6509            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6510            if (r == null) {
6511                return null;
6512            }
6513            return r.packageName;
6514        }
6515    }
6516
6517    @Override
6518    public IIntentSender getIntentSender(int type,
6519            String packageName, IBinder token, String resultWho,
6520            int requestCode, Intent[] intents, String[] resolvedTypes,
6521            int flags, Bundle options, int userId) {
6522        enforceNotIsolatedCaller("getIntentSender");
6523        // Refuse possible leaked file descriptors
6524        if (intents != null) {
6525            if (intents.length < 1) {
6526                throw new IllegalArgumentException("Intents array length must be >= 1");
6527            }
6528            for (int i=0; i<intents.length; i++) {
6529                Intent intent = intents[i];
6530                if (intent != null) {
6531                    if (intent.hasFileDescriptors()) {
6532                        throw new IllegalArgumentException("File descriptors passed in Intent");
6533                    }
6534                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6535                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6536                        throw new IllegalArgumentException(
6537                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6538                    }
6539                    intents[i] = new Intent(intent);
6540                }
6541            }
6542            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6543                throw new IllegalArgumentException(
6544                        "Intent array length does not match resolvedTypes length");
6545            }
6546        }
6547        if (options != null) {
6548            if (options.hasFileDescriptors()) {
6549                throw new IllegalArgumentException("File descriptors passed in options");
6550            }
6551        }
6552
6553        synchronized(this) {
6554            int callingUid = Binder.getCallingUid();
6555            int origUserId = userId;
6556            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6557                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6558                    ALLOW_NON_FULL, "getIntentSender", null);
6559            if (origUserId == UserHandle.USER_CURRENT) {
6560                // We don't want to evaluate this until the pending intent is
6561                // actually executed.  However, we do want to always do the
6562                // security checking for it above.
6563                userId = UserHandle.USER_CURRENT;
6564            }
6565            try {
6566                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6567                    int uid = AppGlobals.getPackageManager()
6568                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6569                    if (!UserHandle.isSameApp(callingUid, uid)) {
6570                        String msg = "Permission Denial: getIntentSender() from pid="
6571                            + Binder.getCallingPid()
6572                            + ", uid=" + Binder.getCallingUid()
6573                            + ", (need uid=" + uid + ")"
6574                            + " is not allowed to send as package " + packageName;
6575                        Slog.w(TAG, msg);
6576                        throw new SecurityException(msg);
6577                    }
6578                }
6579
6580                return getIntentSenderLocked(type, packageName, callingUid, userId,
6581                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6582
6583            } catch (RemoteException e) {
6584                throw new SecurityException(e);
6585            }
6586        }
6587    }
6588
6589    IIntentSender getIntentSenderLocked(int type, String packageName,
6590            int callingUid, int userId, IBinder token, String resultWho,
6591            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6592            Bundle options) {
6593        if (DEBUG_MU)
6594            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6595        ActivityRecord activity = null;
6596        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6597            activity = ActivityRecord.isInStackLocked(token);
6598            if (activity == null) {
6599                return null;
6600            }
6601            if (activity.finishing) {
6602                return null;
6603            }
6604        }
6605
6606        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6607        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6608        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6609        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6610                |PendingIntent.FLAG_UPDATE_CURRENT);
6611
6612        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6613                type, packageName, activity, resultWho,
6614                requestCode, intents, resolvedTypes, flags, options, userId);
6615        WeakReference<PendingIntentRecord> ref;
6616        ref = mIntentSenderRecords.get(key);
6617        PendingIntentRecord rec = ref != null ? ref.get() : null;
6618        if (rec != null) {
6619            if (!cancelCurrent) {
6620                if (updateCurrent) {
6621                    if (rec.key.requestIntent != null) {
6622                        rec.key.requestIntent.replaceExtras(intents != null ?
6623                                intents[intents.length - 1] : null);
6624                    }
6625                    if (intents != null) {
6626                        intents[intents.length-1] = rec.key.requestIntent;
6627                        rec.key.allIntents = intents;
6628                        rec.key.allResolvedTypes = resolvedTypes;
6629                    } else {
6630                        rec.key.allIntents = null;
6631                        rec.key.allResolvedTypes = null;
6632                    }
6633                }
6634                return rec;
6635            }
6636            rec.canceled = true;
6637            mIntentSenderRecords.remove(key);
6638        }
6639        if (noCreate) {
6640            return rec;
6641        }
6642        rec = new PendingIntentRecord(this, key, callingUid);
6643        mIntentSenderRecords.put(key, rec.ref);
6644        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6645            if (activity.pendingResults == null) {
6646                activity.pendingResults
6647                        = new HashSet<WeakReference<PendingIntentRecord>>();
6648            }
6649            activity.pendingResults.add(rec.ref);
6650        }
6651        return rec;
6652    }
6653
6654    @Override
6655    public void cancelIntentSender(IIntentSender sender) {
6656        if (!(sender instanceof PendingIntentRecord)) {
6657            return;
6658        }
6659        synchronized(this) {
6660            PendingIntentRecord rec = (PendingIntentRecord)sender;
6661            try {
6662                int uid = AppGlobals.getPackageManager()
6663                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6664                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6665                    String msg = "Permission Denial: cancelIntentSender() from pid="
6666                        + Binder.getCallingPid()
6667                        + ", uid=" + Binder.getCallingUid()
6668                        + " is not allowed to cancel packges "
6669                        + rec.key.packageName;
6670                    Slog.w(TAG, msg);
6671                    throw new SecurityException(msg);
6672                }
6673            } catch (RemoteException e) {
6674                throw new SecurityException(e);
6675            }
6676            cancelIntentSenderLocked(rec, true);
6677        }
6678    }
6679
6680    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6681        rec.canceled = true;
6682        mIntentSenderRecords.remove(rec.key);
6683        if (cleanActivity && rec.key.activity != null) {
6684            rec.key.activity.pendingResults.remove(rec.ref);
6685        }
6686    }
6687
6688    @Override
6689    public String getPackageForIntentSender(IIntentSender pendingResult) {
6690        if (!(pendingResult instanceof PendingIntentRecord)) {
6691            return null;
6692        }
6693        try {
6694            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6695            return res.key.packageName;
6696        } catch (ClassCastException e) {
6697        }
6698        return null;
6699    }
6700
6701    @Override
6702    public int getUidForIntentSender(IIntentSender sender) {
6703        if (sender instanceof PendingIntentRecord) {
6704            try {
6705                PendingIntentRecord res = (PendingIntentRecord)sender;
6706                return res.uid;
6707            } catch (ClassCastException e) {
6708            }
6709        }
6710        return -1;
6711    }
6712
6713    @Override
6714    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6715        if (!(pendingResult instanceof PendingIntentRecord)) {
6716            return false;
6717        }
6718        try {
6719            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6720            if (res.key.allIntents == null) {
6721                return false;
6722            }
6723            for (int i=0; i<res.key.allIntents.length; i++) {
6724                Intent intent = res.key.allIntents[i];
6725                if (intent.getPackage() != null && intent.getComponent() != null) {
6726                    return false;
6727                }
6728            }
6729            return true;
6730        } catch (ClassCastException e) {
6731        }
6732        return false;
6733    }
6734
6735    @Override
6736    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6737        if (!(pendingResult instanceof PendingIntentRecord)) {
6738            return false;
6739        }
6740        try {
6741            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6742            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6743                return true;
6744            }
6745            return false;
6746        } catch (ClassCastException e) {
6747        }
6748        return false;
6749    }
6750
6751    @Override
6752    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6753        if (!(pendingResult instanceof PendingIntentRecord)) {
6754            return null;
6755        }
6756        try {
6757            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6758            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6759        } catch (ClassCastException e) {
6760        }
6761        return null;
6762    }
6763
6764    @Override
6765    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6766        if (!(pendingResult instanceof PendingIntentRecord)) {
6767            return null;
6768        }
6769        try {
6770            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6771            Intent intent = res.key.requestIntent;
6772            if (intent != null) {
6773                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6774                        || res.lastTagPrefix.equals(prefix))) {
6775                    return res.lastTag;
6776                }
6777                res.lastTagPrefix = prefix;
6778                StringBuilder sb = new StringBuilder(128);
6779                if (prefix != null) {
6780                    sb.append(prefix);
6781                }
6782                if (intent.getAction() != null) {
6783                    sb.append(intent.getAction());
6784                } else if (intent.getComponent() != null) {
6785                    intent.getComponent().appendShortString(sb);
6786                } else {
6787                    sb.append("?");
6788                }
6789                return res.lastTag = sb.toString();
6790            }
6791        } catch (ClassCastException e) {
6792        }
6793        return null;
6794    }
6795
6796    @Override
6797    public void setProcessLimit(int max) {
6798        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6799                "setProcessLimit()");
6800        synchronized (this) {
6801            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6802            mProcessLimitOverride = max;
6803        }
6804        trimApplications();
6805    }
6806
6807    @Override
6808    public int getProcessLimit() {
6809        synchronized (this) {
6810            return mProcessLimitOverride;
6811        }
6812    }
6813
6814    void foregroundTokenDied(ForegroundToken token) {
6815        synchronized (ActivityManagerService.this) {
6816            synchronized (mPidsSelfLocked) {
6817                ForegroundToken cur
6818                    = mForegroundProcesses.get(token.pid);
6819                if (cur != token) {
6820                    return;
6821                }
6822                mForegroundProcesses.remove(token.pid);
6823                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6824                if (pr == null) {
6825                    return;
6826                }
6827                pr.forcingToForeground = null;
6828                updateProcessForegroundLocked(pr, false, false);
6829            }
6830            updateOomAdjLocked();
6831        }
6832    }
6833
6834    @Override
6835    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6836        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6837                "setProcessForeground()");
6838        synchronized(this) {
6839            boolean changed = false;
6840
6841            synchronized (mPidsSelfLocked) {
6842                ProcessRecord pr = mPidsSelfLocked.get(pid);
6843                if (pr == null && isForeground) {
6844                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6845                    return;
6846                }
6847                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6848                if (oldToken != null) {
6849                    oldToken.token.unlinkToDeath(oldToken, 0);
6850                    mForegroundProcesses.remove(pid);
6851                    if (pr != null) {
6852                        pr.forcingToForeground = null;
6853                    }
6854                    changed = true;
6855                }
6856                if (isForeground && token != null) {
6857                    ForegroundToken newToken = new ForegroundToken() {
6858                        @Override
6859                        public void binderDied() {
6860                            foregroundTokenDied(this);
6861                        }
6862                    };
6863                    newToken.pid = pid;
6864                    newToken.token = token;
6865                    try {
6866                        token.linkToDeath(newToken, 0);
6867                        mForegroundProcesses.put(pid, newToken);
6868                        pr.forcingToForeground = token;
6869                        changed = true;
6870                    } catch (RemoteException e) {
6871                        // If the process died while doing this, we will later
6872                        // do the cleanup with the process death link.
6873                    }
6874                }
6875            }
6876
6877            if (changed) {
6878                updateOomAdjLocked();
6879            }
6880        }
6881    }
6882
6883    // =========================================================
6884    // PERMISSIONS
6885    // =========================================================
6886
6887    static class PermissionController extends IPermissionController.Stub {
6888        ActivityManagerService mActivityManagerService;
6889        PermissionController(ActivityManagerService activityManagerService) {
6890            mActivityManagerService = activityManagerService;
6891        }
6892
6893        @Override
6894        public boolean checkPermission(String permission, int pid, int uid) {
6895            return mActivityManagerService.checkPermission(permission, pid,
6896                    uid) == PackageManager.PERMISSION_GRANTED;
6897        }
6898    }
6899
6900    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6901        @Override
6902        public int checkComponentPermission(String permission, int pid, int uid,
6903                int owningUid, boolean exported) {
6904            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6905                    owningUid, exported);
6906        }
6907
6908        @Override
6909        public Object getAMSLock() {
6910            return ActivityManagerService.this;
6911        }
6912    }
6913
6914    /**
6915     * This can be called with or without the global lock held.
6916     */
6917    int checkComponentPermission(String permission, int pid, int uid,
6918            int owningUid, boolean exported) {
6919        // We might be performing an operation on behalf of an indirect binder
6920        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6921        // client identity accordingly before proceeding.
6922        Identity tlsIdentity = sCallerIdentity.get();
6923        if (tlsIdentity != null) {
6924            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6925                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6926            uid = tlsIdentity.uid;
6927            pid = tlsIdentity.pid;
6928        }
6929
6930        if (pid == MY_PID) {
6931            return PackageManager.PERMISSION_GRANTED;
6932        }
6933
6934        return ActivityManager.checkComponentPermission(permission, uid,
6935                owningUid, exported);
6936    }
6937
6938    /**
6939     * As the only public entry point for permissions checking, this method
6940     * can enforce the semantic that requesting a check on a null global
6941     * permission is automatically denied.  (Internally a null permission
6942     * string is used when calling {@link #checkComponentPermission} in cases
6943     * when only uid-based security is needed.)
6944     *
6945     * This can be called with or without the global lock held.
6946     */
6947    @Override
6948    public int checkPermission(String permission, int pid, int uid) {
6949        if (permission == null) {
6950            return PackageManager.PERMISSION_DENIED;
6951        }
6952        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6953    }
6954
6955    /**
6956     * Binder IPC calls go through the public entry point.
6957     * This can be called with or without the global lock held.
6958     */
6959    int checkCallingPermission(String permission) {
6960        return checkPermission(permission,
6961                Binder.getCallingPid(),
6962                UserHandle.getAppId(Binder.getCallingUid()));
6963    }
6964
6965    /**
6966     * This can be called with or without the global lock held.
6967     */
6968    void enforceCallingPermission(String permission, String func) {
6969        if (checkCallingPermission(permission)
6970                == PackageManager.PERMISSION_GRANTED) {
6971            return;
6972        }
6973
6974        String msg = "Permission Denial: " + func + " from pid="
6975                + Binder.getCallingPid()
6976                + ", uid=" + Binder.getCallingUid()
6977                + " requires " + permission;
6978        Slog.w(TAG, msg);
6979        throw new SecurityException(msg);
6980    }
6981
6982    /**
6983     * Determine if UID is holding permissions required to access {@link Uri} in
6984     * the given {@link ProviderInfo}. Final permission checking is always done
6985     * in {@link ContentProvider}.
6986     */
6987    private final boolean checkHoldingPermissionsLocked(
6988            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6989        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6990                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6991        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6992            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6993                    != PERMISSION_GRANTED) {
6994                return false;
6995            }
6996        }
6997        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6998    }
6999
7000    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7001            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7002        if (pi.applicationInfo.uid == uid) {
7003            return true;
7004        } else if (!pi.exported) {
7005            return false;
7006        }
7007
7008        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7009        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7010        try {
7011            // check if target holds top-level <provider> permissions
7012            if (!readMet && pi.readPermission != null && considerUidPermissions
7013                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7014                readMet = true;
7015            }
7016            if (!writeMet && pi.writePermission != null && considerUidPermissions
7017                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7018                writeMet = true;
7019            }
7020
7021            // track if unprotected read/write is allowed; any denied
7022            // <path-permission> below removes this ability
7023            boolean allowDefaultRead = pi.readPermission == null;
7024            boolean allowDefaultWrite = pi.writePermission == null;
7025
7026            // check if target holds any <path-permission> that match uri
7027            final PathPermission[] pps = pi.pathPermissions;
7028            if (pps != null) {
7029                final String path = grantUri.uri.getPath();
7030                int i = pps.length;
7031                while (i > 0 && (!readMet || !writeMet)) {
7032                    i--;
7033                    PathPermission pp = pps[i];
7034                    if (pp.match(path)) {
7035                        if (!readMet) {
7036                            final String pprperm = pp.getReadPermission();
7037                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7038                                    + pprperm + " for " + pp.getPath()
7039                                    + ": match=" + pp.match(path)
7040                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7041                            if (pprperm != null) {
7042                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7043                                        == PERMISSION_GRANTED) {
7044                                    readMet = true;
7045                                } else {
7046                                    allowDefaultRead = false;
7047                                }
7048                            }
7049                        }
7050                        if (!writeMet) {
7051                            final String ppwperm = pp.getWritePermission();
7052                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7053                                    + ppwperm + " for " + pp.getPath()
7054                                    + ": match=" + pp.match(path)
7055                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7056                            if (ppwperm != null) {
7057                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7058                                        == PERMISSION_GRANTED) {
7059                                    writeMet = true;
7060                                } else {
7061                                    allowDefaultWrite = false;
7062                                }
7063                            }
7064                        }
7065                    }
7066                }
7067            }
7068
7069            // grant unprotected <provider> read/write, if not blocked by
7070            // <path-permission> above
7071            if (allowDefaultRead) readMet = true;
7072            if (allowDefaultWrite) writeMet = true;
7073
7074        } catch (RemoteException e) {
7075            return false;
7076        }
7077
7078        return readMet && writeMet;
7079    }
7080
7081    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7082        ProviderInfo pi = null;
7083        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7084        if (cpr != null) {
7085            pi = cpr.info;
7086        } else {
7087            try {
7088                pi = AppGlobals.getPackageManager().resolveContentProvider(
7089                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7090            } catch (RemoteException ex) {
7091            }
7092        }
7093        return pi;
7094    }
7095
7096    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7097        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7098        if (targetUris != null) {
7099            return targetUris.get(grantUri);
7100        }
7101        return null;
7102    }
7103
7104    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7105            String targetPkg, int targetUid, GrantUri grantUri) {
7106        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7107        if (targetUris == null) {
7108            targetUris = Maps.newArrayMap();
7109            mGrantedUriPermissions.put(targetUid, targetUris);
7110        }
7111
7112        UriPermission perm = targetUris.get(grantUri);
7113        if (perm == null) {
7114            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7115            targetUris.put(grantUri, perm);
7116        }
7117
7118        return perm;
7119    }
7120
7121    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7122            final int modeFlags) {
7123        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7124        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7125                : UriPermission.STRENGTH_OWNED;
7126
7127        // Root gets to do everything.
7128        if (uid == 0) {
7129            return true;
7130        }
7131
7132        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7133        if (perms == null) return false;
7134
7135        // First look for exact match
7136        final UriPermission exactPerm = perms.get(grantUri);
7137        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7138            return true;
7139        }
7140
7141        // No exact match, look for prefixes
7142        final int N = perms.size();
7143        for (int i = 0; i < N; i++) {
7144            final UriPermission perm = perms.valueAt(i);
7145            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7146                    && perm.getStrength(modeFlags) >= minStrength) {
7147                return true;
7148            }
7149        }
7150
7151        return false;
7152    }
7153
7154    /**
7155     * @param uri This uri must NOT contain an embedded userId.
7156     * @param userId The userId in which the uri is to be resolved.
7157     */
7158    @Override
7159    public int checkUriPermission(Uri uri, int pid, int uid,
7160            final int modeFlags, int userId) {
7161        enforceNotIsolatedCaller("checkUriPermission");
7162
7163        // Another redirected-binder-call permissions check as in
7164        // {@link checkComponentPermission}.
7165        Identity tlsIdentity = sCallerIdentity.get();
7166        if (tlsIdentity != null) {
7167            uid = tlsIdentity.uid;
7168            pid = tlsIdentity.pid;
7169        }
7170
7171        // Our own process gets to do everything.
7172        if (pid == MY_PID) {
7173            return PackageManager.PERMISSION_GRANTED;
7174        }
7175        synchronized (this) {
7176            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7177                    ? PackageManager.PERMISSION_GRANTED
7178                    : PackageManager.PERMISSION_DENIED;
7179        }
7180    }
7181
7182    /**
7183     * Check if the targetPkg can be granted permission to access uri by
7184     * the callingUid using the given modeFlags.  Throws a security exception
7185     * if callingUid is not allowed to do this.  Returns the uid of the target
7186     * if the URI permission grant should be performed; returns -1 if it is not
7187     * needed (for example targetPkg already has permission to access the URI).
7188     * If you already know the uid of the target, you can supply it in
7189     * lastTargetUid else set that to -1.
7190     */
7191    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7192            final int modeFlags, int lastTargetUid) {
7193        if (!Intent.isAccessUriMode(modeFlags)) {
7194            return -1;
7195        }
7196
7197        if (targetPkg != null) {
7198            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7199                    "Checking grant " + targetPkg + " permission to " + grantUri);
7200        }
7201
7202        final IPackageManager pm = AppGlobals.getPackageManager();
7203
7204        // If this is not a content: uri, we can't do anything with it.
7205        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7206            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7207                    "Can't grant URI permission for non-content URI: " + grantUri);
7208            return -1;
7209        }
7210
7211        final String authority = grantUri.uri.getAuthority();
7212        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7213        if (pi == null) {
7214            Slog.w(TAG, "No content provider found for permission check: " +
7215                    grantUri.uri.toSafeString());
7216            return -1;
7217        }
7218
7219        int targetUid = lastTargetUid;
7220        if (targetUid < 0 && targetPkg != null) {
7221            try {
7222                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7223                if (targetUid < 0) {
7224                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7225                            "Can't grant URI permission no uid for: " + targetPkg);
7226                    return -1;
7227                }
7228            } catch (RemoteException ex) {
7229                return -1;
7230            }
7231        }
7232
7233        if (targetUid >= 0) {
7234            // First...  does the target actually need this permission?
7235            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7236                // No need to grant the target this permission.
7237                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7238                        "Target " + targetPkg + " already has full permission to " + grantUri);
7239                return -1;
7240            }
7241        } else {
7242            // First...  there is no target package, so can anyone access it?
7243            boolean allowed = pi.exported;
7244            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7245                if (pi.readPermission != null) {
7246                    allowed = false;
7247                }
7248            }
7249            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7250                if (pi.writePermission != null) {
7251                    allowed = false;
7252                }
7253            }
7254            if (allowed) {
7255                return -1;
7256            }
7257        }
7258
7259        /* There is a special cross user grant if:
7260         * - The target is on another user.
7261         * - Apps on the current user can access the uri without any uid permissions.
7262         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7263         * grant uri permissions.
7264         */
7265        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7266                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7267                modeFlags, false /*without considering the uid permissions*/);
7268
7269        // Second...  is the provider allowing granting of URI permissions?
7270        if (!specialCrossUserGrant) {
7271            if (!pi.grantUriPermissions) {
7272                throw new SecurityException("Provider " + pi.packageName
7273                        + "/" + pi.name
7274                        + " does not allow granting of Uri permissions (uri "
7275                        + grantUri + ")");
7276            }
7277            if (pi.uriPermissionPatterns != null) {
7278                final int N = pi.uriPermissionPatterns.length;
7279                boolean allowed = false;
7280                for (int i=0; i<N; i++) {
7281                    if (pi.uriPermissionPatterns[i] != null
7282                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7283                        allowed = true;
7284                        break;
7285                    }
7286                }
7287                if (!allowed) {
7288                    throw new SecurityException("Provider " + pi.packageName
7289                            + "/" + pi.name
7290                            + " does not allow granting of permission to path of Uri "
7291                            + grantUri);
7292                }
7293            }
7294        }
7295
7296        // Third...  does the caller itself have permission to access
7297        // this uri?
7298        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7299            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7300                // Require they hold a strong enough Uri permission
7301                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7302                    throw new SecurityException("Uid " + callingUid
7303                            + " does not have permission to uri " + grantUri);
7304                }
7305            }
7306        }
7307        return targetUid;
7308    }
7309
7310    /**
7311     * @param uri This uri must NOT contain an embedded userId.
7312     * @param userId The userId in which the uri is to be resolved.
7313     */
7314    @Override
7315    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7316            final int modeFlags, int userId) {
7317        enforceNotIsolatedCaller("checkGrantUriPermission");
7318        synchronized(this) {
7319            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7320                    new GrantUri(userId, uri, false), modeFlags, -1);
7321        }
7322    }
7323
7324    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7325            final int modeFlags, UriPermissionOwner owner) {
7326        if (!Intent.isAccessUriMode(modeFlags)) {
7327            return;
7328        }
7329
7330        // So here we are: the caller has the assumed permission
7331        // to the uri, and the target doesn't.  Let's now give this to
7332        // the target.
7333
7334        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7335                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7336
7337        final String authority = grantUri.uri.getAuthority();
7338        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7339        if (pi == null) {
7340            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7341            return;
7342        }
7343
7344        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7345            grantUri.prefix = true;
7346        }
7347        final UriPermission perm = findOrCreateUriPermissionLocked(
7348                pi.packageName, targetPkg, targetUid, grantUri);
7349        perm.grantModes(modeFlags, owner);
7350    }
7351
7352    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7353            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7354        if (targetPkg == null) {
7355            throw new NullPointerException("targetPkg");
7356        }
7357        int targetUid;
7358        final IPackageManager pm = AppGlobals.getPackageManager();
7359        try {
7360            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7361        } catch (RemoteException ex) {
7362            return;
7363        }
7364
7365        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7366                targetUid);
7367        if (targetUid < 0) {
7368            return;
7369        }
7370
7371        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7372                owner);
7373    }
7374
7375    static class NeededUriGrants extends ArrayList<GrantUri> {
7376        final String targetPkg;
7377        final int targetUid;
7378        final int flags;
7379
7380        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7381            this.targetPkg = targetPkg;
7382            this.targetUid = targetUid;
7383            this.flags = flags;
7384        }
7385    }
7386
7387    /**
7388     * Like checkGrantUriPermissionLocked, but takes an Intent.
7389     */
7390    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7391            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7392        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7393                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7394                + " clip=" + (intent != null ? intent.getClipData() : null)
7395                + " from " + intent + "; flags=0x"
7396                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7397
7398        if (targetPkg == null) {
7399            throw new NullPointerException("targetPkg");
7400        }
7401
7402        if (intent == null) {
7403            return null;
7404        }
7405        Uri data = intent.getData();
7406        ClipData clip = intent.getClipData();
7407        if (data == null && clip == null) {
7408            return null;
7409        }
7410        // Default userId for uris in the intent (if they don't specify it themselves)
7411        int contentUserHint = intent.getContentUserHint();
7412        if (contentUserHint == UserHandle.USER_CURRENT) {
7413            contentUserHint = UserHandle.getUserId(callingUid);
7414        }
7415        final IPackageManager pm = AppGlobals.getPackageManager();
7416        int targetUid;
7417        if (needed != null) {
7418            targetUid = needed.targetUid;
7419        } else {
7420            try {
7421                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7422            } catch (RemoteException ex) {
7423                return null;
7424            }
7425            if (targetUid < 0) {
7426                if (DEBUG_URI_PERMISSION) {
7427                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7428                            + " on user " + targetUserId);
7429                }
7430                return null;
7431            }
7432        }
7433        if (data != null) {
7434            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7435            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7436                    targetUid);
7437            if (targetUid > 0) {
7438                if (needed == null) {
7439                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7440                }
7441                needed.add(grantUri);
7442            }
7443        }
7444        if (clip != null) {
7445            for (int i=0; i<clip.getItemCount(); i++) {
7446                Uri uri = clip.getItemAt(i).getUri();
7447                if (uri != null) {
7448                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7449                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7450                            targetUid);
7451                    if (targetUid > 0) {
7452                        if (needed == null) {
7453                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7454                        }
7455                        needed.add(grantUri);
7456                    }
7457                } else {
7458                    Intent clipIntent = clip.getItemAt(i).getIntent();
7459                    if (clipIntent != null) {
7460                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7461                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7462                        if (newNeeded != null) {
7463                            needed = newNeeded;
7464                        }
7465                    }
7466                }
7467            }
7468        }
7469
7470        return needed;
7471    }
7472
7473    /**
7474     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7475     */
7476    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7477            UriPermissionOwner owner) {
7478        if (needed != null) {
7479            for (int i=0; i<needed.size(); i++) {
7480                GrantUri grantUri = needed.get(i);
7481                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7482                        grantUri, needed.flags, owner);
7483            }
7484        }
7485    }
7486
7487    void grantUriPermissionFromIntentLocked(int callingUid,
7488            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7489        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7490                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7491        if (needed == null) {
7492            return;
7493        }
7494
7495        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7496    }
7497
7498    /**
7499     * @param uri This uri must NOT contain an embedded userId.
7500     * @param userId The userId in which the uri is to be resolved.
7501     */
7502    @Override
7503    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7504            final int modeFlags, int userId) {
7505        enforceNotIsolatedCaller("grantUriPermission");
7506        GrantUri grantUri = new GrantUri(userId, uri, false);
7507        synchronized(this) {
7508            final ProcessRecord r = getRecordForAppLocked(caller);
7509            if (r == null) {
7510                throw new SecurityException("Unable to find app for caller "
7511                        + caller
7512                        + " when granting permission to uri " + grantUri);
7513            }
7514            if (targetPkg == null) {
7515                throw new IllegalArgumentException("null target");
7516            }
7517            if (grantUri == null) {
7518                throw new IllegalArgumentException("null uri");
7519            }
7520
7521            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7522                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7523                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7524                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7525
7526            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7527                    UserHandle.getUserId(r.uid));
7528        }
7529    }
7530
7531    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7532        if (perm.modeFlags == 0) {
7533            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7534                    perm.targetUid);
7535            if (perms != null) {
7536                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7537                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7538
7539                perms.remove(perm.uri);
7540                if (perms.isEmpty()) {
7541                    mGrantedUriPermissions.remove(perm.targetUid);
7542                }
7543            }
7544        }
7545    }
7546
7547    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7548        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7549
7550        final IPackageManager pm = AppGlobals.getPackageManager();
7551        final String authority = grantUri.uri.getAuthority();
7552        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7553        if (pi == null) {
7554            Slog.w(TAG, "No content provider found for permission revoke: "
7555                    + grantUri.toSafeString());
7556            return;
7557        }
7558
7559        // Does the caller have this permission on the URI?
7560        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7561            // If they don't have direct access to the URI, then revoke any
7562            // ownerless URI permissions that have been granted to them.
7563            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7564            if (perms != null) {
7565                boolean persistChanged = false;
7566                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7567                    final UriPermission perm = it.next();
7568                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7569                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7570                        if (DEBUG_URI_PERMISSION)
7571                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7572                                    " permission to " + perm.uri);
7573                        persistChanged |= perm.revokeModes(
7574                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7575                        if (perm.modeFlags == 0) {
7576                            it.remove();
7577                        }
7578                    }
7579                }
7580                if (perms.isEmpty()) {
7581                    mGrantedUriPermissions.remove(callingUid);
7582                }
7583                if (persistChanged) {
7584                    schedulePersistUriGrants();
7585                }
7586            }
7587            return;
7588        }
7589
7590        boolean persistChanged = false;
7591
7592        // Go through all of the permissions and remove any that match.
7593        int N = mGrantedUriPermissions.size();
7594        for (int i = 0; i < N; i++) {
7595            final int targetUid = mGrantedUriPermissions.keyAt(i);
7596            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7597
7598            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7599                final UriPermission perm = it.next();
7600                if (perm.uri.sourceUserId == grantUri.sourceUserId
7601                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7602                    if (DEBUG_URI_PERMISSION)
7603                        Slog.v(TAG,
7604                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7605                    persistChanged |= perm.revokeModes(
7606                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7607                    if (perm.modeFlags == 0) {
7608                        it.remove();
7609                    }
7610                }
7611            }
7612
7613            if (perms.isEmpty()) {
7614                mGrantedUriPermissions.remove(targetUid);
7615                N--;
7616                i--;
7617            }
7618        }
7619
7620        if (persistChanged) {
7621            schedulePersistUriGrants();
7622        }
7623    }
7624
7625    /**
7626     * @param uri This uri must NOT contain an embedded userId.
7627     * @param userId The userId in which the uri is to be resolved.
7628     */
7629    @Override
7630    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7631            int userId) {
7632        enforceNotIsolatedCaller("revokeUriPermission");
7633        synchronized(this) {
7634            final ProcessRecord r = getRecordForAppLocked(caller);
7635            if (r == null) {
7636                throw new SecurityException("Unable to find app for caller "
7637                        + caller
7638                        + " when revoking permission to uri " + uri);
7639            }
7640            if (uri == null) {
7641                Slog.w(TAG, "revokeUriPermission: null uri");
7642                return;
7643            }
7644
7645            if (!Intent.isAccessUriMode(modeFlags)) {
7646                return;
7647            }
7648
7649            final IPackageManager pm = AppGlobals.getPackageManager();
7650            final String authority = uri.getAuthority();
7651            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7652            if (pi == null) {
7653                Slog.w(TAG, "No content provider found for permission revoke: "
7654                        + uri.toSafeString());
7655                return;
7656            }
7657
7658            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7659        }
7660    }
7661
7662    /**
7663     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7664     * given package.
7665     *
7666     * @param packageName Package name to match, or {@code null} to apply to all
7667     *            packages.
7668     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7669     *            to all users.
7670     * @param persistable If persistable grants should be removed.
7671     */
7672    private void removeUriPermissionsForPackageLocked(
7673            String packageName, int userHandle, boolean persistable) {
7674        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7675            throw new IllegalArgumentException("Must narrow by either package or user");
7676        }
7677
7678        boolean persistChanged = false;
7679
7680        int N = mGrantedUriPermissions.size();
7681        for (int i = 0; i < N; i++) {
7682            final int targetUid = mGrantedUriPermissions.keyAt(i);
7683            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7684
7685            // Only inspect grants matching user
7686            if (userHandle == UserHandle.USER_ALL
7687                    || userHandle == UserHandle.getUserId(targetUid)) {
7688                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7689                    final UriPermission perm = it.next();
7690
7691                    // Only inspect grants matching package
7692                    if (packageName == null || perm.sourcePkg.equals(packageName)
7693                            || perm.targetPkg.equals(packageName)) {
7694                        persistChanged |= perm.revokeModes(persistable
7695                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7696
7697                        // Only remove when no modes remain; any persisted grants
7698                        // will keep this alive.
7699                        if (perm.modeFlags == 0) {
7700                            it.remove();
7701                        }
7702                    }
7703                }
7704
7705                if (perms.isEmpty()) {
7706                    mGrantedUriPermissions.remove(targetUid);
7707                    N--;
7708                    i--;
7709                }
7710            }
7711        }
7712
7713        if (persistChanged) {
7714            schedulePersistUriGrants();
7715        }
7716    }
7717
7718    @Override
7719    public IBinder newUriPermissionOwner(String name) {
7720        enforceNotIsolatedCaller("newUriPermissionOwner");
7721        synchronized(this) {
7722            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7723            return owner.getExternalTokenLocked();
7724        }
7725    }
7726
7727    /**
7728     * @param uri This uri must NOT contain an embedded userId.
7729     * @param sourceUserId The userId in which the uri is to be resolved.
7730     * @param targetUserId The userId of the app that receives the grant.
7731     */
7732    @Override
7733    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7734            final int modeFlags, int sourceUserId, int targetUserId) {
7735        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7736                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7737        synchronized(this) {
7738            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7739            if (owner == null) {
7740                throw new IllegalArgumentException("Unknown owner: " + token);
7741            }
7742            if (fromUid != Binder.getCallingUid()) {
7743                if (Binder.getCallingUid() != Process.myUid()) {
7744                    // Only system code can grant URI permissions on behalf
7745                    // of other users.
7746                    throw new SecurityException("nice try");
7747                }
7748            }
7749            if (targetPkg == null) {
7750                throw new IllegalArgumentException("null target");
7751            }
7752            if (uri == null) {
7753                throw new IllegalArgumentException("null uri");
7754            }
7755
7756            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7757                    modeFlags, owner, targetUserId);
7758        }
7759    }
7760
7761    /**
7762     * @param uri This uri must NOT contain an embedded userId.
7763     * @param userId The userId in which the uri is to be resolved.
7764     */
7765    @Override
7766    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7767        synchronized(this) {
7768            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7769            if (owner == null) {
7770                throw new IllegalArgumentException("Unknown owner: " + token);
7771            }
7772
7773            if (uri == null) {
7774                owner.removeUriPermissionsLocked(mode);
7775            } else {
7776                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7777            }
7778        }
7779    }
7780
7781    private void schedulePersistUriGrants() {
7782        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7783            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7784                    10 * DateUtils.SECOND_IN_MILLIS);
7785        }
7786    }
7787
7788    private void writeGrantedUriPermissions() {
7789        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7790
7791        // Snapshot permissions so we can persist without lock
7792        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7793        synchronized (this) {
7794            final int size = mGrantedUriPermissions.size();
7795            for (int i = 0; i < size; i++) {
7796                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7797                for (UriPermission perm : perms.values()) {
7798                    if (perm.persistedModeFlags != 0) {
7799                        persist.add(perm.snapshot());
7800                    }
7801                }
7802            }
7803        }
7804
7805        FileOutputStream fos = null;
7806        try {
7807            fos = mGrantFile.startWrite();
7808
7809            XmlSerializer out = new FastXmlSerializer();
7810            out.setOutput(fos, "utf-8");
7811            out.startDocument(null, true);
7812            out.startTag(null, TAG_URI_GRANTS);
7813            for (UriPermission.Snapshot perm : persist) {
7814                out.startTag(null, TAG_URI_GRANT);
7815                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7816                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7817                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7818                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7819                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7820                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7821                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7822                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7823                out.endTag(null, TAG_URI_GRANT);
7824            }
7825            out.endTag(null, TAG_URI_GRANTS);
7826            out.endDocument();
7827
7828            mGrantFile.finishWrite(fos);
7829        } catch (IOException e) {
7830            if (fos != null) {
7831                mGrantFile.failWrite(fos);
7832            }
7833        }
7834    }
7835
7836    private void readGrantedUriPermissionsLocked() {
7837        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7838
7839        final long now = System.currentTimeMillis();
7840
7841        FileInputStream fis = null;
7842        try {
7843            fis = mGrantFile.openRead();
7844            final XmlPullParser in = Xml.newPullParser();
7845            in.setInput(fis, null);
7846
7847            int type;
7848            while ((type = in.next()) != END_DOCUMENT) {
7849                final String tag = in.getName();
7850                if (type == START_TAG) {
7851                    if (TAG_URI_GRANT.equals(tag)) {
7852                        final int sourceUserId;
7853                        final int targetUserId;
7854                        final int userHandle = readIntAttribute(in,
7855                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7856                        if (userHandle != UserHandle.USER_NULL) {
7857                            // For backwards compatibility.
7858                            sourceUserId = userHandle;
7859                            targetUserId = userHandle;
7860                        } else {
7861                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7862                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7863                        }
7864                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7865                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7866                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7867                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7868                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7869                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7870
7871                        // Sanity check that provider still belongs to source package
7872                        final ProviderInfo pi = getProviderInfoLocked(
7873                                uri.getAuthority(), sourceUserId);
7874                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7875                            int targetUid = -1;
7876                            try {
7877                                targetUid = AppGlobals.getPackageManager()
7878                                        .getPackageUid(targetPkg, targetUserId);
7879                            } catch (RemoteException e) {
7880                            }
7881                            if (targetUid != -1) {
7882                                final UriPermission perm = findOrCreateUriPermissionLocked(
7883                                        sourcePkg, targetPkg, targetUid,
7884                                        new GrantUri(sourceUserId, uri, prefix));
7885                                perm.initPersistedModes(modeFlags, createdTime);
7886                            }
7887                        } else {
7888                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7889                                    + " but instead found " + pi);
7890                        }
7891                    }
7892                }
7893            }
7894        } catch (FileNotFoundException e) {
7895            // Missing grants is okay
7896        } catch (IOException e) {
7897            Log.wtf(TAG, "Failed reading Uri grants", e);
7898        } catch (XmlPullParserException e) {
7899            Log.wtf(TAG, "Failed reading Uri grants", e);
7900        } finally {
7901            IoUtils.closeQuietly(fis);
7902        }
7903    }
7904
7905    /**
7906     * @param uri This uri must NOT contain an embedded userId.
7907     * @param userId The userId in which the uri is to be resolved.
7908     */
7909    @Override
7910    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7911        enforceNotIsolatedCaller("takePersistableUriPermission");
7912
7913        Preconditions.checkFlagsArgument(modeFlags,
7914                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7915
7916        synchronized (this) {
7917            final int callingUid = Binder.getCallingUid();
7918            boolean persistChanged = false;
7919            GrantUri grantUri = new GrantUri(userId, uri, false);
7920
7921            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7922                    new GrantUri(userId, uri, false));
7923            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7924                    new GrantUri(userId, uri, true));
7925
7926            final boolean exactValid = (exactPerm != null)
7927                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7928            final boolean prefixValid = (prefixPerm != null)
7929                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7930
7931            if (!(exactValid || prefixValid)) {
7932                throw new SecurityException("No persistable permission grants found for UID "
7933                        + callingUid + " and Uri " + grantUri.toSafeString());
7934            }
7935
7936            if (exactValid) {
7937                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7938            }
7939            if (prefixValid) {
7940                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7941            }
7942
7943            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7944
7945            if (persistChanged) {
7946                schedulePersistUriGrants();
7947            }
7948        }
7949    }
7950
7951    /**
7952     * @param uri This uri must NOT contain an embedded userId.
7953     * @param userId The userId in which the uri is to be resolved.
7954     */
7955    @Override
7956    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7957        enforceNotIsolatedCaller("releasePersistableUriPermission");
7958
7959        Preconditions.checkFlagsArgument(modeFlags,
7960                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7961
7962        synchronized (this) {
7963            final int callingUid = Binder.getCallingUid();
7964            boolean persistChanged = false;
7965
7966            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7967                    new GrantUri(userId, uri, false));
7968            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7969                    new GrantUri(userId, uri, true));
7970            if (exactPerm == null && prefixPerm == null) {
7971                throw new SecurityException("No permission grants found for UID " + callingUid
7972                        + " and Uri " + uri.toSafeString());
7973            }
7974
7975            if (exactPerm != null) {
7976                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7977                removeUriPermissionIfNeededLocked(exactPerm);
7978            }
7979            if (prefixPerm != null) {
7980                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7981                removeUriPermissionIfNeededLocked(prefixPerm);
7982            }
7983
7984            if (persistChanged) {
7985                schedulePersistUriGrants();
7986            }
7987        }
7988    }
7989
7990    /**
7991     * Prune any older {@link UriPermission} for the given UID until outstanding
7992     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7993     *
7994     * @return if any mutations occured that require persisting.
7995     */
7996    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7997        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7998        if (perms == null) return false;
7999        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8000
8001        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8002        for (UriPermission perm : perms.values()) {
8003            if (perm.persistedModeFlags != 0) {
8004                persisted.add(perm);
8005            }
8006        }
8007
8008        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8009        if (trimCount <= 0) return false;
8010
8011        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8012        for (int i = 0; i < trimCount; i++) {
8013            final UriPermission perm = persisted.get(i);
8014
8015            if (DEBUG_URI_PERMISSION) {
8016                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8017            }
8018
8019            perm.releasePersistableModes(~0);
8020            removeUriPermissionIfNeededLocked(perm);
8021        }
8022
8023        return true;
8024    }
8025
8026    @Override
8027    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8028            String packageName, boolean incoming) {
8029        enforceNotIsolatedCaller("getPersistedUriPermissions");
8030        Preconditions.checkNotNull(packageName, "packageName");
8031
8032        final int callingUid = Binder.getCallingUid();
8033        final IPackageManager pm = AppGlobals.getPackageManager();
8034        try {
8035            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8036            if (packageUid != callingUid) {
8037                throw new SecurityException(
8038                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8039            }
8040        } catch (RemoteException e) {
8041            throw new SecurityException("Failed to verify package name ownership");
8042        }
8043
8044        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8045        synchronized (this) {
8046            if (incoming) {
8047                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8048                        callingUid);
8049                if (perms == null) {
8050                    Slog.w(TAG, "No permission grants found for " + packageName);
8051                } else {
8052                    for (UriPermission perm : perms.values()) {
8053                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8054                            result.add(perm.buildPersistedPublicApiObject());
8055                        }
8056                    }
8057                }
8058            } else {
8059                final int size = mGrantedUriPermissions.size();
8060                for (int i = 0; i < size; i++) {
8061                    final ArrayMap<GrantUri, UriPermission> perms =
8062                            mGrantedUriPermissions.valueAt(i);
8063                    for (UriPermission perm : perms.values()) {
8064                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8065                            result.add(perm.buildPersistedPublicApiObject());
8066                        }
8067                    }
8068                }
8069            }
8070        }
8071        return new ParceledListSlice<android.content.UriPermission>(result);
8072    }
8073
8074    @Override
8075    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8076        synchronized (this) {
8077            ProcessRecord app =
8078                who != null ? getRecordForAppLocked(who) : null;
8079            if (app == null) return;
8080
8081            Message msg = Message.obtain();
8082            msg.what = WAIT_FOR_DEBUGGER_MSG;
8083            msg.obj = app;
8084            msg.arg1 = waiting ? 1 : 0;
8085            mHandler.sendMessage(msg);
8086        }
8087    }
8088
8089    @Override
8090    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8091        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8092        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8093        outInfo.availMem = Process.getFreeMemory();
8094        outInfo.totalMem = Process.getTotalMemory();
8095        outInfo.threshold = homeAppMem;
8096        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8097        outInfo.hiddenAppThreshold = cachedAppMem;
8098        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8099                ProcessList.SERVICE_ADJ);
8100        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8101                ProcessList.VISIBLE_APP_ADJ);
8102        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8103                ProcessList.FOREGROUND_APP_ADJ);
8104    }
8105
8106    // =========================================================
8107    // TASK MANAGEMENT
8108    // =========================================================
8109
8110    @Override
8111    public List<IAppTask> getAppTasks(String callingPackage) {
8112        int callingUid = Binder.getCallingUid();
8113        long ident = Binder.clearCallingIdentity();
8114
8115        synchronized(this) {
8116            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8117            try {
8118                if (localLOGV) Slog.v(TAG, "getAppTasks");
8119
8120                final int N = mRecentTasks.size();
8121                for (int i = 0; i < N; i++) {
8122                    TaskRecord tr = mRecentTasks.get(i);
8123                    // Skip tasks that do not match the caller.  We don't need to verify
8124                    // callingPackage, because we are also limiting to callingUid and know
8125                    // that will limit to the correct security sandbox.
8126                    if (tr.effectiveUid != callingUid) {
8127                        continue;
8128                    }
8129                    Intent intent = tr.getBaseIntent();
8130                    if (intent == null ||
8131                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8132                        continue;
8133                    }
8134                    ActivityManager.RecentTaskInfo taskInfo =
8135                            createRecentTaskInfoFromTaskRecord(tr);
8136                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8137                    list.add(taskImpl);
8138                }
8139            } finally {
8140                Binder.restoreCallingIdentity(ident);
8141            }
8142            return list;
8143        }
8144    }
8145
8146    @Override
8147    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8148        final int callingUid = Binder.getCallingUid();
8149        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8150
8151        synchronized(this) {
8152            if (localLOGV) Slog.v(
8153                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8154
8155            final boolean allowed = checkCallingPermission(
8156                    android.Manifest.permission.GET_TASKS)
8157                    == PackageManager.PERMISSION_GRANTED;
8158            if (!allowed) {
8159                Slog.w(TAG, "getTasks: caller " + callingUid
8160                        + " does not hold GET_TASKS; limiting output");
8161            }
8162
8163            // TODO: Improve with MRU list from all ActivityStacks.
8164            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8165        }
8166
8167        return list;
8168    }
8169
8170    TaskRecord getMostRecentTask() {
8171        return mRecentTasks.get(0);
8172    }
8173
8174    /**
8175     * Creates a new RecentTaskInfo from a TaskRecord.
8176     */
8177    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8178        // Update the task description to reflect any changes in the task stack
8179        tr.updateTaskDescription();
8180
8181        // Compose the recent task info
8182        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8183        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8184        rti.persistentId = tr.taskId;
8185        rti.baseIntent = new Intent(tr.getBaseIntent());
8186        rti.origActivity = tr.origActivity;
8187        rti.description = tr.lastDescription;
8188        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8189        rti.userId = tr.userId;
8190        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8191        rti.firstActiveTime = tr.firstActiveTime;
8192        rti.lastActiveTime = tr.lastActiveTime;
8193        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8194        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8195        return rti;
8196    }
8197
8198    @Override
8199    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8200        final int callingUid = Binder.getCallingUid();
8201        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8202                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8203
8204        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8205        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8206        synchronized (this) {
8207            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8208                    == PackageManager.PERMISSION_GRANTED;
8209            if (!allowed) {
8210                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8211                        + " does not hold GET_TASKS; limiting output");
8212            }
8213            final boolean detailed = checkCallingPermission(
8214                    android.Manifest.permission.GET_DETAILED_TASKS)
8215                    == PackageManager.PERMISSION_GRANTED;
8216
8217            final int N = mRecentTasks.size();
8218            ArrayList<ActivityManager.RecentTaskInfo> res
8219                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8220                            maxNum < N ? maxNum : N);
8221
8222            final Set<Integer> includedUsers;
8223            if (includeProfiles) {
8224                includedUsers = getProfileIdsLocked(userId);
8225            } else {
8226                includedUsers = new HashSet<Integer>();
8227            }
8228            includedUsers.add(Integer.valueOf(userId));
8229
8230            for (int i=0; i<N && maxNum > 0; i++) {
8231                TaskRecord tr = mRecentTasks.get(i);
8232                // Only add calling user or related users recent tasks
8233                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8234                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8235                    continue;
8236                }
8237
8238                // Return the entry if desired by the caller.  We always return
8239                // the first entry, because callers always expect this to be the
8240                // foreground app.  We may filter others if the caller has
8241                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8242                // we should exclude the entry.
8243
8244                if (i == 0
8245                        || withExcluded
8246                        || (tr.intent == null)
8247                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8248                                == 0)) {
8249                    if (!allowed) {
8250                        // If the caller doesn't have the GET_TASKS permission, then only
8251                        // allow them to see a small subset of tasks -- their own and home.
8252                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8253                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8254                            continue;
8255                        }
8256                    }
8257                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8258                        if (tr.stack != null && tr.stack.isHomeStack()) {
8259                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8260                            continue;
8261                        }
8262                    }
8263                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8264                        // Don't include auto remove tasks that are finished or finishing.
8265                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8266                                + tr);
8267                        continue;
8268                    }
8269                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8270                            && !tr.isAvailable) {
8271                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8272                        continue;
8273                    }
8274
8275                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8276                    if (!detailed) {
8277                        rti.baseIntent.replaceExtras((Bundle)null);
8278                    }
8279
8280                    res.add(rti);
8281                    maxNum--;
8282                }
8283            }
8284            return res;
8285        }
8286    }
8287
8288    private TaskRecord recentTaskForIdLocked(int id) {
8289        final int N = mRecentTasks.size();
8290            for (int i=0; i<N; i++) {
8291                TaskRecord tr = mRecentTasks.get(i);
8292                if (tr.taskId == id) {
8293                    return tr;
8294                }
8295            }
8296            return null;
8297    }
8298
8299    @Override
8300    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8301        synchronized (this) {
8302            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8303                    "getTaskThumbnail()");
8304            TaskRecord tr = recentTaskForIdLocked(id);
8305            if (tr != null) {
8306                return tr.getTaskThumbnailLocked();
8307            }
8308        }
8309        return null;
8310    }
8311
8312    @Override
8313    public int addAppTask(IBinder activityToken, Intent intent,
8314            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8315        final int callingUid = Binder.getCallingUid();
8316        final long callingIdent = Binder.clearCallingIdentity();
8317
8318        try {
8319            synchronized (this) {
8320                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8321                if (r == null) {
8322                    throw new IllegalArgumentException("Activity does not exist; token="
8323                            + activityToken);
8324                }
8325                ComponentName comp = intent.getComponent();
8326                if (comp == null) {
8327                    throw new IllegalArgumentException("Intent " + intent
8328                            + " must specify explicit component");
8329                }
8330                if (thumbnail.getWidth() != mThumbnailWidth
8331                        || thumbnail.getHeight() != mThumbnailHeight) {
8332                    throw new IllegalArgumentException("Bad thumbnail size: got "
8333                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8334                            + mThumbnailWidth + "x" + mThumbnailHeight);
8335                }
8336                if (intent.getSelector() != null) {
8337                    intent.setSelector(null);
8338                }
8339                if (intent.getSourceBounds() != null) {
8340                    intent.setSourceBounds(null);
8341                }
8342                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8343                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8344                        // The caller has added this as an auto-remove task...  that makes no
8345                        // sense, so turn off auto-remove.
8346                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8347                    }
8348                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8349                    // Must be a new task.
8350                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8351                }
8352                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8353                    mLastAddedTaskActivity = null;
8354                }
8355                ActivityInfo ainfo = mLastAddedTaskActivity;
8356                if (ainfo == null) {
8357                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8358                            comp, 0, UserHandle.getUserId(callingUid));
8359                    if (ainfo.applicationInfo.uid != callingUid) {
8360                        throw new SecurityException(
8361                                "Can't add task for another application: target uid="
8362                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8363                    }
8364                }
8365
8366                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8367                        intent, description);
8368
8369                int trimIdx = trimRecentsForTask(task, false);
8370                if (trimIdx >= 0) {
8371                    // If this would have caused a trim, then we'll abort because that
8372                    // means it would be added at the end of the list but then just removed.
8373                    return -1;
8374                }
8375
8376                final int N = mRecentTasks.size();
8377                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8378                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8379                    tr.removedFromRecents(mTaskPersister);
8380                }
8381
8382                task.inRecents = true;
8383                mRecentTasks.add(task);
8384                r.task.stack.addTask(task, false, false);
8385
8386                task.setLastThumbnail(thumbnail);
8387                task.freeLastThumbnail();
8388
8389                return task.taskId;
8390            }
8391        } finally {
8392            Binder.restoreCallingIdentity(callingIdent);
8393        }
8394    }
8395
8396    @Override
8397    public Point getAppTaskThumbnailSize() {
8398        synchronized (this) {
8399            return new Point(mThumbnailWidth,  mThumbnailHeight);
8400        }
8401    }
8402
8403    @Override
8404    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8405        synchronized (this) {
8406            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8407            if (r != null) {
8408                r.setTaskDescription(td);
8409                r.task.updateTaskDescription();
8410            }
8411        }
8412    }
8413
8414    @Override
8415    public Bitmap getTaskDescriptionIcon(String filename) {
8416        if (!FileUtils.isValidExtFilename(filename)
8417                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8418            throw new IllegalArgumentException("Bad filename: " + filename);
8419        }
8420        return mTaskPersister.getTaskDescriptionIcon(filename);
8421    }
8422
8423    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8424        mRecentTasks.remove(tr);
8425        tr.removedFromRecents(mTaskPersister);
8426        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8427        Intent baseIntent = new Intent(
8428                tr.intent != null ? tr.intent : tr.affinityIntent);
8429        ComponentName component = baseIntent.getComponent();
8430        if (component == null) {
8431            Slog.w(TAG, "Now component for base intent of task: " + tr);
8432            return;
8433        }
8434
8435        // Find any running services associated with this app.
8436        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8437
8438        if (killProcesses) {
8439            // Find any running processes associated with this app.
8440            final String pkg = component.getPackageName();
8441            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8442            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8443            for (int i=0; i<pmap.size(); i++) {
8444                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8445                for (int j=0; j<uids.size(); j++) {
8446                    ProcessRecord proc = uids.valueAt(j);
8447                    if (proc.userId != tr.userId) {
8448                        continue;
8449                    }
8450                    if (!proc.pkgList.containsKey(pkg)) {
8451                        continue;
8452                    }
8453                    procs.add(proc);
8454                }
8455            }
8456
8457            // Kill the running processes.
8458            for (int i=0; i<procs.size(); i++) {
8459                ProcessRecord pr = procs.get(i);
8460                if (pr == mHomeProcess) {
8461                    // Don't kill the home process along with tasks from the same package.
8462                    continue;
8463                }
8464                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8465                    pr.kill("remove task", true);
8466                } else {
8467                    pr.waitingToKill = "remove task";
8468                }
8469            }
8470        }
8471    }
8472
8473    /**
8474     * Removes the task with the specified task id.
8475     *
8476     * @param taskId Identifier of the task to be removed.
8477     * @param flags Additional operational flags.  May be 0 or
8478     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8479     * @return Returns true if the given task was found and removed.
8480     */
8481    private boolean removeTaskByIdLocked(int taskId, int flags) {
8482        TaskRecord tr = recentTaskForIdLocked(taskId);
8483        if (tr != null) {
8484            tr.removeTaskActivitiesLocked();
8485            cleanUpRemovedTaskLocked(tr, flags);
8486            if (tr.isPersistable) {
8487                notifyTaskPersisterLocked(null, true);
8488            }
8489            return true;
8490        }
8491        return false;
8492    }
8493
8494    @Override
8495    public boolean removeTask(int taskId, int flags) {
8496        synchronized (this) {
8497            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8498                    "removeTask()");
8499            long ident = Binder.clearCallingIdentity();
8500            try {
8501                return removeTaskByIdLocked(taskId, flags);
8502            } finally {
8503                Binder.restoreCallingIdentity(ident);
8504            }
8505        }
8506    }
8507
8508    /**
8509     * TODO: Add mController hook
8510     */
8511    @Override
8512    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8513        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8514                "moveTaskToFront()");
8515
8516        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8517        synchronized(this) {
8518            moveTaskToFrontLocked(taskId, flags, options);
8519        }
8520    }
8521
8522    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8523        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8524                Binder.getCallingUid(), -1, -1, "Task to front")) {
8525            ActivityOptions.abort(options);
8526            return;
8527        }
8528        final long origId = Binder.clearCallingIdentity();
8529        try {
8530            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8531            if (task == null) {
8532                return;
8533            }
8534            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8535                mStackSupervisor.showLockTaskToast();
8536                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8537                return;
8538            }
8539            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8540            if (prev != null && prev.isRecentsActivity()) {
8541                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8542            }
8543            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8544        } finally {
8545            Binder.restoreCallingIdentity(origId);
8546        }
8547        ActivityOptions.abort(options);
8548    }
8549
8550    @Override
8551    public void moveTaskToBack(int taskId) {
8552        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8553                "moveTaskToBack()");
8554
8555        synchronized(this) {
8556            TaskRecord tr = recentTaskForIdLocked(taskId);
8557            if (tr != null) {
8558                if (tr == mStackSupervisor.mLockTaskModeTask) {
8559                    mStackSupervisor.showLockTaskToast();
8560                    return;
8561                }
8562                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8563                ActivityStack stack = tr.stack;
8564                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8565                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8566                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8567                        return;
8568                    }
8569                }
8570                final long origId = Binder.clearCallingIdentity();
8571                try {
8572                    stack.moveTaskToBackLocked(taskId, null);
8573                } finally {
8574                    Binder.restoreCallingIdentity(origId);
8575                }
8576            }
8577        }
8578    }
8579
8580    /**
8581     * Moves an activity, and all of the other activities within the same task, to the bottom
8582     * of the history stack.  The activity's order within the task is unchanged.
8583     *
8584     * @param token A reference to the activity we wish to move
8585     * @param nonRoot If false then this only works if the activity is the root
8586     *                of a task; if true it will work for any activity in a task.
8587     * @return Returns true if the move completed, false if not.
8588     */
8589    @Override
8590    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8591        enforceNotIsolatedCaller("moveActivityTaskToBack");
8592        synchronized(this) {
8593            final long origId = Binder.clearCallingIdentity();
8594            try {
8595                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8596                if (taskId >= 0) {
8597                    if ((mStackSupervisor.mLockTaskModeTask != null)
8598                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8599                        mStackSupervisor.showLockTaskToast();
8600                        return false;
8601                    }
8602                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8603                }
8604            } finally {
8605                Binder.restoreCallingIdentity(origId);
8606            }
8607        }
8608        return false;
8609    }
8610
8611    @Override
8612    public void moveTaskBackwards(int task) {
8613        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8614                "moveTaskBackwards()");
8615
8616        synchronized(this) {
8617            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8618                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8619                return;
8620            }
8621            final long origId = Binder.clearCallingIdentity();
8622            moveTaskBackwardsLocked(task);
8623            Binder.restoreCallingIdentity(origId);
8624        }
8625    }
8626
8627    private final void moveTaskBackwardsLocked(int task) {
8628        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8629    }
8630
8631    @Override
8632    public IBinder getHomeActivityToken() throws RemoteException {
8633        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8634                "getHomeActivityToken()");
8635        synchronized (this) {
8636            return mStackSupervisor.getHomeActivityToken();
8637        }
8638    }
8639
8640    @Override
8641    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8642            IActivityContainerCallback callback) throws RemoteException {
8643        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8644                "createActivityContainer()");
8645        synchronized (this) {
8646            if (parentActivityToken == null) {
8647                throw new IllegalArgumentException("parent token must not be null");
8648            }
8649            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8650            if (r == null) {
8651                return null;
8652            }
8653            if (callback == null) {
8654                throw new IllegalArgumentException("callback must not be null");
8655            }
8656            return mStackSupervisor.createActivityContainer(r, callback);
8657        }
8658    }
8659
8660    @Override
8661    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8662        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8663                "deleteActivityContainer()");
8664        synchronized (this) {
8665            mStackSupervisor.deleteActivityContainer(container);
8666        }
8667    }
8668
8669    @Override
8670    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8671            throws RemoteException {
8672        synchronized (this) {
8673            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8674            if (stack != null) {
8675                return stack.mActivityContainer;
8676            }
8677            return null;
8678        }
8679    }
8680
8681    @Override
8682    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8683        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8684                "moveTaskToStack()");
8685        if (stackId == HOME_STACK_ID) {
8686            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8687                    new RuntimeException("here").fillInStackTrace());
8688        }
8689        synchronized (this) {
8690            long ident = Binder.clearCallingIdentity();
8691            try {
8692                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8693                        + stackId + " toTop=" + toTop);
8694                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8695            } finally {
8696                Binder.restoreCallingIdentity(ident);
8697            }
8698        }
8699    }
8700
8701    @Override
8702    public void resizeStack(int stackBoxId, Rect bounds) {
8703        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8704                "resizeStackBox()");
8705        long ident = Binder.clearCallingIdentity();
8706        try {
8707            mWindowManager.resizeStack(stackBoxId, bounds);
8708        } finally {
8709            Binder.restoreCallingIdentity(ident);
8710        }
8711    }
8712
8713    @Override
8714    public List<StackInfo> getAllStackInfos() {
8715        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8716                "getAllStackInfos()");
8717        long ident = Binder.clearCallingIdentity();
8718        try {
8719            synchronized (this) {
8720                return mStackSupervisor.getAllStackInfosLocked();
8721            }
8722        } finally {
8723            Binder.restoreCallingIdentity(ident);
8724        }
8725    }
8726
8727    @Override
8728    public StackInfo getStackInfo(int stackId) {
8729        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8730                "getStackInfo()");
8731        long ident = Binder.clearCallingIdentity();
8732        try {
8733            synchronized (this) {
8734                return mStackSupervisor.getStackInfoLocked(stackId);
8735            }
8736        } finally {
8737            Binder.restoreCallingIdentity(ident);
8738        }
8739    }
8740
8741    @Override
8742    public boolean isInHomeStack(int taskId) {
8743        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744                "getStackInfo()");
8745        long ident = Binder.clearCallingIdentity();
8746        try {
8747            synchronized (this) {
8748                TaskRecord tr = recentTaskForIdLocked(taskId);
8749                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8750            }
8751        } finally {
8752            Binder.restoreCallingIdentity(ident);
8753        }
8754    }
8755
8756    @Override
8757    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8758        synchronized(this) {
8759            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8760        }
8761    }
8762
8763    private boolean isLockTaskAuthorized(String pkg) {
8764        final DevicePolicyManager dpm = (DevicePolicyManager)
8765                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8766        try {
8767            int uid = mContext.getPackageManager().getPackageUid(pkg,
8768                    Binder.getCallingUserHandle().getIdentifier());
8769            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8770        } catch (NameNotFoundException e) {
8771            return false;
8772        }
8773    }
8774
8775    void startLockTaskMode(TaskRecord task) {
8776        final String pkg;
8777        synchronized (this) {
8778            pkg = task.intent.getComponent().getPackageName();
8779        }
8780        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8781        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8782            final TaskRecord taskRecord = task;
8783            mHandler.post(new Runnable() {
8784                @Override
8785                public void run() {
8786                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8787                }
8788            });
8789            return;
8790        }
8791        long ident = Binder.clearCallingIdentity();
8792        try {
8793            synchronized (this) {
8794                // Since we lost lock on task, make sure it is still there.
8795                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8796                if (task != null) {
8797                    if (!isSystemInitiated
8798                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8799                        throw new IllegalArgumentException("Invalid task, not in foreground");
8800                    }
8801                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8802                }
8803            }
8804        } finally {
8805            Binder.restoreCallingIdentity(ident);
8806        }
8807    }
8808
8809    @Override
8810    public void startLockTaskMode(int taskId) {
8811        final TaskRecord task;
8812        long ident = Binder.clearCallingIdentity();
8813        try {
8814            synchronized (this) {
8815                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8816            }
8817        } finally {
8818            Binder.restoreCallingIdentity(ident);
8819        }
8820        if (task != null) {
8821            startLockTaskMode(task);
8822        }
8823    }
8824
8825    @Override
8826    public void startLockTaskMode(IBinder token) {
8827        final TaskRecord task;
8828        long ident = Binder.clearCallingIdentity();
8829        try {
8830            synchronized (this) {
8831                final ActivityRecord r = ActivityRecord.forToken(token);
8832                if (r == null) {
8833                    return;
8834                }
8835                task = r.task;
8836            }
8837        } finally {
8838            Binder.restoreCallingIdentity(ident);
8839        }
8840        if (task != null) {
8841            startLockTaskMode(task);
8842        }
8843    }
8844
8845    @Override
8846    public void startLockTaskModeOnCurrent() throws RemoteException {
8847        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8848                "startLockTaskModeOnCurrent");
8849        ActivityRecord r = null;
8850        synchronized (this) {
8851            r = mStackSupervisor.topRunningActivityLocked();
8852        }
8853        startLockTaskMode(r.task);
8854    }
8855
8856    @Override
8857    public void stopLockTaskMode() {
8858        // Verify that the user matches the package of the intent for the TaskRecord
8859        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8860        // and stopLockTaskMode.
8861        final int callingUid = Binder.getCallingUid();
8862        if (callingUid != Process.SYSTEM_UID) {
8863            try {
8864                String pkg =
8865                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8866                int uid = mContext.getPackageManager().getPackageUid(pkg,
8867                        Binder.getCallingUserHandle().getIdentifier());
8868                if (uid != callingUid) {
8869                    throw new SecurityException("Invalid uid, expected " + uid);
8870                }
8871            } catch (NameNotFoundException e) {
8872                Log.d(TAG, "stopLockTaskMode " + e);
8873                return;
8874            }
8875        }
8876        long ident = Binder.clearCallingIdentity();
8877        try {
8878            Log.d(TAG, "stopLockTaskMode");
8879            // Stop lock task
8880            synchronized (this) {
8881                mStackSupervisor.setLockTaskModeLocked(null, false);
8882            }
8883        } finally {
8884            Binder.restoreCallingIdentity(ident);
8885        }
8886    }
8887
8888    @Override
8889    public void stopLockTaskModeOnCurrent() throws RemoteException {
8890        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8891                "stopLockTaskModeOnCurrent");
8892        long ident = Binder.clearCallingIdentity();
8893        try {
8894            stopLockTaskMode();
8895        } finally {
8896            Binder.restoreCallingIdentity(ident);
8897        }
8898    }
8899
8900    @Override
8901    public boolean isInLockTaskMode() {
8902        synchronized (this) {
8903            return mStackSupervisor.isInLockTaskMode();
8904        }
8905    }
8906
8907    // =========================================================
8908    // CONTENT PROVIDERS
8909    // =========================================================
8910
8911    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8912        List<ProviderInfo> providers = null;
8913        try {
8914            providers = AppGlobals.getPackageManager().
8915                queryContentProviders(app.processName, app.uid,
8916                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8917        } catch (RemoteException ex) {
8918        }
8919        if (DEBUG_MU)
8920            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8921        int userId = app.userId;
8922        if (providers != null) {
8923            int N = providers.size();
8924            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8925            for (int i=0; i<N; i++) {
8926                ProviderInfo cpi =
8927                    (ProviderInfo)providers.get(i);
8928                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8929                        cpi.name, cpi.flags);
8930                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8931                    // This is a singleton provider, but a user besides the
8932                    // default user is asking to initialize a process it runs
8933                    // in...  well, no, it doesn't actually run in this process,
8934                    // it runs in the process of the default user.  Get rid of it.
8935                    providers.remove(i);
8936                    N--;
8937                    i--;
8938                    continue;
8939                }
8940
8941                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8942                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8943                if (cpr == null) {
8944                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8945                    mProviderMap.putProviderByClass(comp, cpr);
8946                }
8947                if (DEBUG_MU)
8948                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8949                app.pubProviders.put(cpi.name, cpr);
8950                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8951                    // Don't add this if it is a platform component that is marked
8952                    // to run in multiple processes, because this is actually
8953                    // part of the framework so doesn't make sense to track as a
8954                    // separate apk in the process.
8955                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8956                            mProcessStats);
8957                }
8958                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8959            }
8960        }
8961        return providers;
8962    }
8963
8964    /**
8965     * Check if {@link ProcessRecord} has a possible chance at accessing the
8966     * given {@link ProviderInfo}. Final permission checking is always done
8967     * in {@link ContentProvider}.
8968     */
8969    private final String checkContentProviderPermissionLocked(
8970            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8971        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8972        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8973        boolean checkedGrants = false;
8974        if (checkUser) {
8975            // Looking for cross-user grants before enforcing the typical cross-users permissions
8976            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8977            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8978                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8979                    return null;
8980                }
8981                checkedGrants = true;
8982            }
8983            userId = handleIncomingUser(callingPid, callingUid, userId,
8984                    false, ALLOW_NON_FULL,
8985                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8986            if (userId != tmpTargetUserId) {
8987                // When we actually went to determine the final targer user ID, this ended
8988                // up different than our initial check for the authority.  This is because
8989                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8990                // SELF.  So we need to re-check the grants again.
8991                checkedGrants = false;
8992            }
8993        }
8994        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8995                cpi.applicationInfo.uid, cpi.exported)
8996                == PackageManager.PERMISSION_GRANTED) {
8997            return null;
8998        }
8999        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9000                cpi.applicationInfo.uid, cpi.exported)
9001                == PackageManager.PERMISSION_GRANTED) {
9002            return null;
9003        }
9004
9005        PathPermission[] pps = cpi.pathPermissions;
9006        if (pps != null) {
9007            int i = pps.length;
9008            while (i > 0) {
9009                i--;
9010                PathPermission pp = pps[i];
9011                String pprperm = pp.getReadPermission();
9012                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9013                        cpi.applicationInfo.uid, cpi.exported)
9014                        == PackageManager.PERMISSION_GRANTED) {
9015                    return null;
9016                }
9017                String ppwperm = pp.getWritePermission();
9018                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9019                        cpi.applicationInfo.uid, cpi.exported)
9020                        == PackageManager.PERMISSION_GRANTED) {
9021                    return null;
9022                }
9023            }
9024        }
9025        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9026            return null;
9027        }
9028
9029        String msg;
9030        if (!cpi.exported) {
9031            msg = "Permission Denial: opening provider " + cpi.name
9032                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9033                    + ", uid=" + callingUid + ") that is not exported from uid "
9034                    + cpi.applicationInfo.uid;
9035        } else {
9036            msg = "Permission Denial: opening provider " + cpi.name
9037                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9038                    + ", uid=" + callingUid + ") requires "
9039                    + cpi.readPermission + " or " + cpi.writePermission;
9040        }
9041        Slog.w(TAG, msg);
9042        return msg;
9043    }
9044
9045    /**
9046     * Returns if the ContentProvider has granted a uri to callingUid
9047     */
9048    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9049        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9050        if (perms != null) {
9051            for (int i=perms.size()-1; i>=0; i--) {
9052                GrantUri grantUri = perms.keyAt(i);
9053                if (grantUri.sourceUserId == userId || !checkUser) {
9054                    if (matchesProvider(grantUri.uri, cpi)) {
9055                        return true;
9056                    }
9057                }
9058            }
9059        }
9060        return false;
9061    }
9062
9063    /**
9064     * Returns true if the uri authority is one of the authorities specified in the provider.
9065     */
9066    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9067        String uriAuth = uri.getAuthority();
9068        String cpiAuth = cpi.authority;
9069        if (cpiAuth.indexOf(';') == -1) {
9070            return cpiAuth.equals(uriAuth);
9071        }
9072        String[] cpiAuths = cpiAuth.split(";");
9073        int length = cpiAuths.length;
9074        for (int i = 0; i < length; i++) {
9075            if (cpiAuths[i].equals(uriAuth)) return true;
9076        }
9077        return false;
9078    }
9079
9080    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9081            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9082        if (r != null) {
9083            for (int i=0; i<r.conProviders.size(); i++) {
9084                ContentProviderConnection conn = r.conProviders.get(i);
9085                if (conn.provider == cpr) {
9086                    if (DEBUG_PROVIDER) Slog.v(TAG,
9087                            "Adding provider requested by "
9088                            + r.processName + " from process "
9089                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9090                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9091                    if (stable) {
9092                        conn.stableCount++;
9093                        conn.numStableIncs++;
9094                    } else {
9095                        conn.unstableCount++;
9096                        conn.numUnstableIncs++;
9097                    }
9098                    return conn;
9099                }
9100            }
9101            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9102            if (stable) {
9103                conn.stableCount = 1;
9104                conn.numStableIncs = 1;
9105            } else {
9106                conn.unstableCount = 1;
9107                conn.numUnstableIncs = 1;
9108            }
9109            cpr.connections.add(conn);
9110            r.conProviders.add(conn);
9111            return conn;
9112        }
9113        cpr.addExternalProcessHandleLocked(externalProcessToken);
9114        return null;
9115    }
9116
9117    boolean decProviderCountLocked(ContentProviderConnection conn,
9118            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9119        if (conn != null) {
9120            cpr = conn.provider;
9121            if (DEBUG_PROVIDER) Slog.v(TAG,
9122                    "Removing provider requested by "
9123                    + conn.client.processName + " from process "
9124                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9125                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9126            if (stable) {
9127                conn.stableCount--;
9128            } else {
9129                conn.unstableCount--;
9130            }
9131            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9132                cpr.connections.remove(conn);
9133                conn.client.conProviders.remove(conn);
9134                return true;
9135            }
9136            return false;
9137        }
9138        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9139        return false;
9140    }
9141
9142    private void checkTime(long startTime, String where) {
9143        long now = SystemClock.elapsedRealtime();
9144        if ((now-startTime) > 1000) {
9145            // If we are taking more than a second, log about it.
9146            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9147        }
9148    }
9149
9150    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9151            String name, IBinder token, boolean stable, int userId) {
9152        ContentProviderRecord cpr;
9153        ContentProviderConnection conn = null;
9154        ProviderInfo cpi = null;
9155
9156        synchronized(this) {
9157            long startTime = SystemClock.elapsedRealtime();
9158
9159            ProcessRecord r = null;
9160            if (caller != null) {
9161                r = getRecordForAppLocked(caller);
9162                if (r == null) {
9163                    throw new SecurityException(
9164                            "Unable to find app for caller " + caller
9165                          + " (pid=" + Binder.getCallingPid()
9166                          + ") when getting content provider " + name);
9167                }
9168            }
9169
9170            boolean checkCrossUser = true;
9171
9172            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9173
9174            // First check if this content provider has been published...
9175            cpr = mProviderMap.getProviderByName(name, userId);
9176            // If that didn't work, check if it exists for user 0 and then
9177            // verify that it's a singleton provider before using it.
9178            if (cpr == null && userId != UserHandle.USER_OWNER) {
9179                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9180                if (cpr != null) {
9181                    cpi = cpr.info;
9182                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9183                            cpi.name, cpi.flags)
9184                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9185                        userId = UserHandle.USER_OWNER;
9186                        checkCrossUser = false;
9187                    } else {
9188                        cpr = null;
9189                        cpi = null;
9190                    }
9191                }
9192            }
9193
9194            boolean providerRunning = cpr != null;
9195            if (providerRunning) {
9196                cpi = cpr.info;
9197                String msg;
9198                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9199                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9200                        != null) {
9201                    throw new SecurityException(msg);
9202                }
9203                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9204
9205                if (r != null && cpr.canRunHere(r)) {
9206                    // This provider has been published or is in the process
9207                    // of being published...  but it is also allowed to run
9208                    // in the caller's process, so don't make a connection
9209                    // and just let the caller instantiate its own instance.
9210                    ContentProviderHolder holder = cpr.newHolder(null);
9211                    // don't give caller the provider object, it needs
9212                    // to make its own.
9213                    holder.provider = null;
9214                    return holder;
9215                }
9216
9217                final long origId = Binder.clearCallingIdentity();
9218
9219                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9220
9221                // In this case the provider instance already exists, so we can
9222                // return it right away.
9223                conn = incProviderCountLocked(r, cpr, token, stable);
9224                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9225                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9226                        // If this is a perceptible app accessing the provider,
9227                        // make sure to count it as being accessed and thus
9228                        // back up on the LRU list.  This is good because
9229                        // content providers are often expensive to start.
9230                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9231                        updateLruProcessLocked(cpr.proc, false, null);
9232                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9233                    }
9234                }
9235
9236                if (cpr.proc != null) {
9237                    if (false) {
9238                        if (cpr.name.flattenToShortString().equals(
9239                                "com.android.providers.calendar/.CalendarProvider2")) {
9240                            Slog.v(TAG, "****************** KILLING "
9241                                + cpr.name.flattenToShortString());
9242                            Process.killProcess(cpr.proc.pid);
9243                        }
9244                    }
9245                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9246                    boolean success = updateOomAdjLocked(cpr.proc);
9247                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9248                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9249                    // NOTE: there is still a race here where a signal could be
9250                    // pending on the process even though we managed to update its
9251                    // adj level.  Not sure what to do about this, but at least
9252                    // the race is now smaller.
9253                    if (!success) {
9254                        // Uh oh...  it looks like the provider's process
9255                        // has been killed on us.  We need to wait for a new
9256                        // process to be started, and make sure its death
9257                        // doesn't kill our process.
9258                        Slog.i(TAG,
9259                                "Existing provider " + cpr.name.flattenToShortString()
9260                                + " is crashing; detaching " + r);
9261                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9262                        checkTime(startTime, "getContentProviderImpl: before appDied");
9263                        appDiedLocked(cpr.proc);
9264                        checkTime(startTime, "getContentProviderImpl: after appDied");
9265                        if (!lastRef) {
9266                            // This wasn't the last ref our process had on
9267                            // the provider...  we have now been killed, bail.
9268                            return null;
9269                        }
9270                        providerRunning = false;
9271                        conn = null;
9272                    }
9273                }
9274
9275                Binder.restoreCallingIdentity(origId);
9276            }
9277
9278            boolean singleton;
9279            if (!providerRunning) {
9280                try {
9281                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9282                    cpi = AppGlobals.getPackageManager().
9283                        resolveContentProvider(name,
9284                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9285                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9286                } catch (RemoteException ex) {
9287                }
9288                if (cpi == null) {
9289                    return null;
9290                }
9291                // If the provider is a singleton AND
9292                // (it's a call within the same user || the provider is a
9293                // privileged app)
9294                // Then allow connecting to the singleton provider
9295                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9296                        cpi.name, cpi.flags)
9297                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9298                if (singleton) {
9299                    userId = UserHandle.USER_OWNER;
9300                }
9301                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9302                checkTime(startTime, "getContentProviderImpl: got app info for user");
9303
9304                String msg;
9305                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9306                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9307                        != null) {
9308                    throw new SecurityException(msg);
9309                }
9310                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9311
9312                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9313                        && !cpi.processName.equals("system")) {
9314                    // If this content provider does not run in the system
9315                    // process, and the system is not yet ready to run other
9316                    // processes, then fail fast instead of hanging.
9317                    throw new IllegalArgumentException(
9318                            "Attempt to launch content provider before system ready");
9319                }
9320
9321                // Make sure that the user who owns this provider is started.  If not,
9322                // we don't want to allow it to run.
9323                if (mStartedUsers.get(userId) == null) {
9324                    Slog.w(TAG, "Unable to launch app "
9325                            + cpi.applicationInfo.packageName + "/"
9326                            + cpi.applicationInfo.uid + " for provider "
9327                            + name + ": user " + userId + " is stopped");
9328                    return null;
9329                }
9330
9331                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9332                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9333                cpr = mProviderMap.getProviderByClass(comp, userId);
9334                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9335                final boolean firstClass = cpr == null;
9336                if (firstClass) {
9337                    try {
9338                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9339                        ApplicationInfo ai =
9340                            AppGlobals.getPackageManager().
9341                                getApplicationInfo(
9342                                        cpi.applicationInfo.packageName,
9343                                        STOCK_PM_FLAGS, userId);
9344                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9345                        if (ai == null) {
9346                            Slog.w(TAG, "No package info for content provider "
9347                                    + cpi.name);
9348                            return null;
9349                        }
9350                        ai = getAppInfoForUser(ai, userId);
9351                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9352                    } catch (RemoteException ex) {
9353                        // pm is in same process, this will never happen.
9354                    }
9355                }
9356
9357                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9358
9359                if (r != null && cpr.canRunHere(r)) {
9360                    // If this is a multiprocess provider, then just return its
9361                    // info and allow the caller to instantiate it.  Only do
9362                    // this if the provider is the same user as the caller's
9363                    // process, or can run as root (so can be in any process).
9364                    return cpr.newHolder(null);
9365                }
9366
9367                if (DEBUG_PROVIDER) {
9368                    RuntimeException e = new RuntimeException("here");
9369                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9370                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9371                }
9372
9373                // This is single process, and our app is now connecting to it.
9374                // See if we are already in the process of launching this
9375                // provider.
9376                final int N = mLaunchingProviders.size();
9377                int i;
9378                for (i=0; i<N; i++) {
9379                    if (mLaunchingProviders.get(i) == cpr) {
9380                        break;
9381                    }
9382                }
9383
9384                // If the provider is not already being launched, then get it
9385                // started.
9386                if (i >= N) {
9387                    final long origId = Binder.clearCallingIdentity();
9388
9389                    try {
9390                        // Content provider is now in use, its package can't be stopped.
9391                        try {
9392                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9393                            AppGlobals.getPackageManager().setPackageStoppedState(
9394                                    cpr.appInfo.packageName, false, userId);
9395                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9396                        } catch (RemoteException e) {
9397                        } catch (IllegalArgumentException e) {
9398                            Slog.w(TAG, "Failed trying to unstop package "
9399                                    + cpr.appInfo.packageName + ": " + e);
9400                        }
9401
9402                        // Use existing process if already started
9403                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9404                        ProcessRecord proc = getProcessRecordLocked(
9405                                cpi.processName, cpr.appInfo.uid, false);
9406                        if (proc != null && proc.thread != null) {
9407                            if (DEBUG_PROVIDER) {
9408                                Slog.d(TAG, "Installing in existing process " + proc);
9409                            }
9410                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9411                            proc.pubProviders.put(cpi.name, cpr);
9412                            try {
9413                                proc.thread.scheduleInstallProvider(cpi);
9414                            } catch (RemoteException e) {
9415                            }
9416                        } else {
9417                            checkTime(startTime, "getContentProviderImpl: before start process");
9418                            proc = startProcessLocked(cpi.processName,
9419                                    cpr.appInfo, false, 0, "content provider",
9420                                    new ComponentName(cpi.applicationInfo.packageName,
9421                                            cpi.name), false, false, false);
9422                            checkTime(startTime, "getContentProviderImpl: after start process");
9423                            if (proc == null) {
9424                                Slog.w(TAG, "Unable to launch app "
9425                                        + cpi.applicationInfo.packageName + "/"
9426                                        + cpi.applicationInfo.uid + " for provider "
9427                                        + name + ": process is bad");
9428                                return null;
9429                            }
9430                        }
9431                        cpr.launchingApp = proc;
9432                        mLaunchingProviders.add(cpr);
9433                    } finally {
9434                        Binder.restoreCallingIdentity(origId);
9435                    }
9436                }
9437
9438                checkTime(startTime, "getContentProviderImpl: updating data structures");
9439
9440                // Make sure the provider is published (the same provider class
9441                // may be published under multiple names).
9442                if (firstClass) {
9443                    mProviderMap.putProviderByClass(comp, cpr);
9444                }
9445
9446                mProviderMap.putProviderByName(name, cpr);
9447                conn = incProviderCountLocked(r, cpr, token, stable);
9448                if (conn != null) {
9449                    conn.waiting = true;
9450                }
9451            }
9452            checkTime(startTime, "getContentProviderImpl: done!");
9453        }
9454
9455        // Wait for the provider to be published...
9456        synchronized (cpr) {
9457            while (cpr.provider == null) {
9458                if (cpr.launchingApp == null) {
9459                    Slog.w(TAG, "Unable to launch app "
9460                            + cpi.applicationInfo.packageName + "/"
9461                            + cpi.applicationInfo.uid + " for provider "
9462                            + name + ": launching app became null");
9463                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9464                            UserHandle.getUserId(cpi.applicationInfo.uid),
9465                            cpi.applicationInfo.packageName,
9466                            cpi.applicationInfo.uid, name);
9467                    return null;
9468                }
9469                try {
9470                    if (DEBUG_MU) {
9471                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9472                                + cpr.launchingApp);
9473                    }
9474                    if (conn != null) {
9475                        conn.waiting = true;
9476                    }
9477                    cpr.wait();
9478                } catch (InterruptedException ex) {
9479                } finally {
9480                    if (conn != null) {
9481                        conn.waiting = false;
9482                    }
9483                }
9484            }
9485        }
9486        return cpr != null ? cpr.newHolder(conn) : null;
9487    }
9488
9489    @Override
9490    public final ContentProviderHolder getContentProvider(
9491            IApplicationThread caller, String name, int userId, boolean stable) {
9492        enforceNotIsolatedCaller("getContentProvider");
9493        if (caller == null) {
9494            String msg = "null IApplicationThread when getting content provider "
9495                    + name;
9496            Slog.w(TAG, msg);
9497            throw new SecurityException(msg);
9498        }
9499        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9500        // with cross-user grant.
9501        return getContentProviderImpl(caller, name, null, stable, userId);
9502    }
9503
9504    public ContentProviderHolder getContentProviderExternal(
9505            String name, int userId, IBinder token) {
9506        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9507            "Do not have permission in call getContentProviderExternal()");
9508        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9509                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9510        return getContentProviderExternalUnchecked(name, token, userId);
9511    }
9512
9513    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9514            IBinder token, int userId) {
9515        return getContentProviderImpl(null, name, token, true, userId);
9516    }
9517
9518    /**
9519     * Drop a content provider from a ProcessRecord's bookkeeping
9520     */
9521    public void removeContentProvider(IBinder connection, boolean stable) {
9522        enforceNotIsolatedCaller("removeContentProvider");
9523        long ident = Binder.clearCallingIdentity();
9524        try {
9525            synchronized (this) {
9526                ContentProviderConnection conn;
9527                try {
9528                    conn = (ContentProviderConnection)connection;
9529                } catch (ClassCastException e) {
9530                    String msg ="removeContentProvider: " + connection
9531                            + " not a ContentProviderConnection";
9532                    Slog.w(TAG, msg);
9533                    throw new IllegalArgumentException(msg);
9534                }
9535                if (conn == null) {
9536                    throw new NullPointerException("connection is null");
9537                }
9538                if (decProviderCountLocked(conn, null, null, stable)) {
9539                    updateOomAdjLocked();
9540                }
9541            }
9542        } finally {
9543            Binder.restoreCallingIdentity(ident);
9544        }
9545    }
9546
9547    public void removeContentProviderExternal(String name, IBinder token) {
9548        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9549            "Do not have permission in call removeContentProviderExternal()");
9550        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9551    }
9552
9553    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9554        synchronized (this) {
9555            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9556            if(cpr == null) {
9557                //remove from mProvidersByClass
9558                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9559                return;
9560            }
9561
9562            //update content provider record entry info
9563            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9564            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9565            if (localCpr.hasExternalProcessHandles()) {
9566                if (localCpr.removeExternalProcessHandleLocked(token)) {
9567                    updateOomAdjLocked();
9568                } else {
9569                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9570                            + " with no external reference for token: "
9571                            + token + ".");
9572                }
9573            } else {
9574                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9575                        + " with no external references.");
9576            }
9577        }
9578    }
9579
9580    public final void publishContentProviders(IApplicationThread caller,
9581            List<ContentProviderHolder> providers) {
9582        if (providers == null) {
9583            return;
9584        }
9585
9586        enforceNotIsolatedCaller("publishContentProviders");
9587        synchronized (this) {
9588            final ProcessRecord r = getRecordForAppLocked(caller);
9589            if (DEBUG_MU)
9590                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9591            if (r == null) {
9592                throw new SecurityException(
9593                        "Unable to find app for caller " + caller
9594                      + " (pid=" + Binder.getCallingPid()
9595                      + ") when publishing content providers");
9596            }
9597
9598            final long origId = Binder.clearCallingIdentity();
9599
9600            final int N = providers.size();
9601            for (int i=0; i<N; i++) {
9602                ContentProviderHolder src = providers.get(i);
9603                if (src == null || src.info == null || src.provider == null) {
9604                    continue;
9605                }
9606                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9607                if (DEBUG_MU)
9608                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9609                if (dst != null) {
9610                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9611                    mProviderMap.putProviderByClass(comp, dst);
9612                    String names[] = dst.info.authority.split(";");
9613                    for (int j = 0; j < names.length; j++) {
9614                        mProviderMap.putProviderByName(names[j], dst);
9615                    }
9616
9617                    int NL = mLaunchingProviders.size();
9618                    int j;
9619                    for (j=0; j<NL; j++) {
9620                        if (mLaunchingProviders.get(j) == dst) {
9621                            mLaunchingProviders.remove(j);
9622                            j--;
9623                            NL--;
9624                        }
9625                    }
9626                    synchronized (dst) {
9627                        dst.provider = src.provider;
9628                        dst.proc = r;
9629                        dst.notifyAll();
9630                    }
9631                    updateOomAdjLocked(r);
9632                }
9633            }
9634
9635            Binder.restoreCallingIdentity(origId);
9636        }
9637    }
9638
9639    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9640        ContentProviderConnection conn;
9641        try {
9642            conn = (ContentProviderConnection)connection;
9643        } catch (ClassCastException e) {
9644            String msg ="refContentProvider: " + connection
9645                    + " not a ContentProviderConnection";
9646            Slog.w(TAG, msg);
9647            throw new IllegalArgumentException(msg);
9648        }
9649        if (conn == null) {
9650            throw new NullPointerException("connection is null");
9651        }
9652
9653        synchronized (this) {
9654            if (stable > 0) {
9655                conn.numStableIncs += stable;
9656            }
9657            stable = conn.stableCount + stable;
9658            if (stable < 0) {
9659                throw new IllegalStateException("stableCount < 0: " + stable);
9660            }
9661
9662            if (unstable > 0) {
9663                conn.numUnstableIncs += unstable;
9664            }
9665            unstable = conn.unstableCount + unstable;
9666            if (unstable < 0) {
9667                throw new IllegalStateException("unstableCount < 0: " + unstable);
9668            }
9669
9670            if ((stable+unstable) <= 0) {
9671                throw new IllegalStateException("ref counts can't go to zero here: stable="
9672                        + stable + " unstable=" + unstable);
9673            }
9674            conn.stableCount = stable;
9675            conn.unstableCount = unstable;
9676            return !conn.dead;
9677        }
9678    }
9679
9680    public void unstableProviderDied(IBinder connection) {
9681        ContentProviderConnection conn;
9682        try {
9683            conn = (ContentProviderConnection)connection;
9684        } catch (ClassCastException e) {
9685            String msg ="refContentProvider: " + connection
9686                    + " not a ContentProviderConnection";
9687            Slog.w(TAG, msg);
9688            throw new IllegalArgumentException(msg);
9689        }
9690        if (conn == null) {
9691            throw new NullPointerException("connection is null");
9692        }
9693
9694        // Safely retrieve the content provider associated with the connection.
9695        IContentProvider provider;
9696        synchronized (this) {
9697            provider = conn.provider.provider;
9698        }
9699
9700        if (provider == null) {
9701            // Um, yeah, we're way ahead of you.
9702            return;
9703        }
9704
9705        // Make sure the caller is being honest with us.
9706        if (provider.asBinder().pingBinder()) {
9707            // Er, no, still looks good to us.
9708            synchronized (this) {
9709                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9710                        + " says " + conn + " died, but we don't agree");
9711                return;
9712            }
9713        }
9714
9715        // Well look at that!  It's dead!
9716        synchronized (this) {
9717            if (conn.provider.provider != provider) {
9718                // But something changed...  good enough.
9719                return;
9720            }
9721
9722            ProcessRecord proc = conn.provider.proc;
9723            if (proc == null || proc.thread == null) {
9724                // Seems like the process is already cleaned up.
9725                return;
9726            }
9727
9728            // As far as we're concerned, this is just like receiving a
9729            // death notification...  just a bit prematurely.
9730            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9731                    + ") early provider death");
9732            final long ident = Binder.clearCallingIdentity();
9733            try {
9734                appDiedLocked(proc);
9735            } finally {
9736                Binder.restoreCallingIdentity(ident);
9737            }
9738        }
9739    }
9740
9741    @Override
9742    public void appNotRespondingViaProvider(IBinder connection) {
9743        enforceCallingPermission(
9744                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9745
9746        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9747        if (conn == null) {
9748            Slog.w(TAG, "ContentProviderConnection is null");
9749            return;
9750        }
9751
9752        final ProcessRecord host = conn.provider.proc;
9753        if (host == null) {
9754            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9755            return;
9756        }
9757
9758        final long token = Binder.clearCallingIdentity();
9759        try {
9760            appNotResponding(host, null, null, false, "ContentProvider not responding");
9761        } finally {
9762            Binder.restoreCallingIdentity(token);
9763        }
9764    }
9765
9766    public final void installSystemProviders() {
9767        List<ProviderInfo> providers;
9768        synchronized (this) {
9769            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9770            providers = generateApplicationProvidersLocked(app);
9771            if (providers != null) {
9772                for (int i=providers.size()-1; i>=0; i--) {
9773                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9774                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9775                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9776                                + ": not system .apk");
9777                        providers.remove(i);
9778                    }
9779                }
9780            }
9781        }
9782        if (providers != null) {
9783            mSystemThread.installSystemProviders(providers);
9784        }
9785
9786        mCoreSettingsObserver = new CoreSettingsObserver(this);
9787
9788        //mUsageStatsService.monitorPackages();
9789    }
9790
9791    /**
9792     * Allows apps to retrieve the MIME type of a URI.
9793     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9794     * users, then it does not need permission to access the ContentProvider.
9795     * Either, it needs cross-user uri grants.
9796     *
9797     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9798     *
9799     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9800     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9801     */
9802    public String getProviderMimeType(Uri uri, int userId) {
9803        enforceNotIsolatedCaller("getProviderMimeType");
9804        final String name = uri.getAuthority();
9805        int callingUid = Binder.getCallingUid();
9806        int callingPid = Binder.getCallingPid();
9807        long ident = 0;
9808        boolean clearedIdentity = false;
9809        userId = unsafeConvertIncomingUser(userId);
9810        if (canClearIdentity(callingPid, callingUid, userId)) {
9811            clearedIdentity = true;
9812            ident = Binder.clearCallingIdentity();
9813        }
9814        ContentProviderHolder holder = null;
9815        try {
9816            holder = getContentProviderExternalUnchecked(name, null, userId);
9817            if (holder != null) {
9818                return holder.provider.getType(uri);
9819            }
9820        } catch (RemoteException e) {
9821            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9822            return null;
9823        } finally {
9824            // We need to clear the identity to call removeContentProviderExternalUnchecked
9825            if (!clearedIdentity) {
9826                ident = Binder.clearCallingIdentity();
9827            }
9828            try {
9829                if (holder != null) {
9830                    removeContentProviderExternalUnchecked(name, null, userId);
9831                }
9832            } finally {
9833                Binder.restoreCallingIdentity(ident);
9834            }
9835        }
9836
9837        return null;
9838    }
9839
9840    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9841        if (UserHandle.getUserId(callingUid) == userId) {
9842            return true;
9843        }
9844        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9845                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9846                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9847                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9848                return true;
9849        }
9850        return false;
9851    }
9852
9853    // =========================================================
9854    // GLOBAL MANAGEMENT
9855    // =========================================================
9856
9857    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9858            boolean isolated, int isolatedUid) {
9859        String proc = customProcess != null ? customProcess : info.processName;
9860        BatteryStatsImpl.Uid.Proc ps = null;
9861        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9862        int uid = info.uid;
9863        if (isolated) {
9864            if (isolatedUid == 0) {
9865                int userId = UserHandle.getUserId(uid);
9866                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9867                while (true) {
9868                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9869                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9870                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9871                    }
9872                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9873                    mNextIsolatedProcessUid++;
9874                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9875                        // No process for this uid, use it.
9876                        break;
9877                    }
9878                    stepsLeft--;
9879                    if (stepsLeft <= 0) {
9880                        return null;
9881                    }
9882                }
9883            } else {
9884                // Special case for startIsolatedProcess (internal only), where
9885                // the uid of the isolated process is specified by the caller.
9886                uid = isolatedUid;
9887            }
9888        }
9889        return new ProcessRecord(stats, info, proc, uid);
9890    }
9891
9892    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9893            String abiOverride) {
9894        ProcessRecord app;
9895        if (!isolated) {
9896            app = getProcessRecordLocked(info.processName, info.uid, true);
9897        } else {
9898            app = null;
9899        }
9900
9901        if (app == null) {
9902            app = newProcessRecordLocked(info, null, isolated, 0);
9903            mProcessNames.put(info.processName, app.uid, app);
9904            if (isolated) {
9905                mIsolatedProcesses.put(app.uid, app);
9906            }
9907            updateLruProcessLocked(app, false, null);
9908            updateOomAdjLocked();
9909        }
9910
9911        // This package really, really can not be stopped.
9912        try {
9913            AppGlobals.getPackageManager().setPackageStoppedState(
9914                    info.packageName, false, UserHandle.getUserId(app.uid));
9915        } catch (RemoteException e) {
9916        } catch (IllegalArgumentException e) {
9917            Slog.w(TAG, "Failed trying to unstop package "
9918                    + info.packageName + ": " + e);
9919        }
9920
9921        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9922                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9923            app.persistent = true;
9924            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9925        }
9926        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9927            mPersistentStartingProcesses.add(app);
9928            startProcessLocked(app, "added application", app.processName, abiOverride,
9929                    null /* entryPoint */, null /* entryPointArgs */);
9930        }
9931
9932        return app;
9933    }
9934
9935    public void unhandledBack() {
9936        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9937                "unhandledBack()");
9938
9939        synchronized(this) {
9940            final long origId = Binder.clearCallingIdentity();
9941            try {
9942                getFocusedStack().unhandledBackLocked();
9943            } finally {
9944                Binder.restoreCallingIdentity(origId);
9945            }
9946        }
9947    }
9948
9949    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9950        enforceNotIsolatedCaller("openContentUri");
9951        final int userId = UserHandle.getCallingUserId();
9952        String name = uri.getAuthority();
9953        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9954        ParcelFileDescriptor pfd = null;
9955        if (cph != null) {
9956            // We record the binder invoker's uid in thread-local storage before
9957            // going to the content provider to open the file.  Later, in the code
9958            // that handles all permissions checks, we look for this uid and use
9959            // that rather than the Activity Manager's own uid.  The effect is that
9960            // we do the check against the caller's permissions even though it looks
9961            // to the content provider like the Activity Manager itself is making
9962            // the request.
9963            sCallerIdentity.set(new Identity(
9964                    Binder.getCallingPid(), Binder.getCallingUid()));
9965            try {
9966                pfd = cph.provider.openFile(null, uri, "r", null);
9967            } catch (FileNotFoundException e) {
9968                // do nothing; pfd will be returned null
9969            } finally {
9970                // Ensure that whatever happens, we clean up the identity state
9971                sCallerIdentity.remove();
9972            }
9973
9974            // We've got the fd now, so we're done with the provider.
9975            removeContentProviderExternalUnchecked(name, null, userId);
9976        } else {
9977            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9978        }
9979        return pfd;
9980    }
9981
9982    // Actually is sleeping or shutting down or whatever else in the future
9983    // is an inactive state.
9984    public boolean isSleepingOrShuttingDown() {
9985        return isSleeping() || mShuttingDown;
9986    }
9987
9988    public boolean isSleeping() {
9989        return mSleeping;
9990    }
9991
9992    void goingToSleep() {
9993        synchronized(this) {
9994            mWentToSleep = true;
9995            goToSleepIfNeededLocked();
9996        }
9997    }
9998
9999    void finishRunningVoiceLocked() {
10000        if (mRunningVoice) {
10001            mRunningVoice = false;
10002            goToSleepIfNeededLocked();
10003        }
10004    }
10005
10006    void goToSleepIfNeededLocked() {
10007        if (mWentToSleep && !mRunningVoice) {
10008            if (!mSleeping) {
10009                mSleeping = true;
10010                mStackSupervisor.goingToSleepLocked();
10011
10012                // Initialize the wake times of all processes.
10013                checkExcessivePowerUsageLocked(false);
10014                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10015                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10016                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10017            }
10018        }
10019    }
10020
10021    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10022        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10023            // Never persist the home stack.
10024            return;
10025        }
10026        mTaskPersister.wakeup(task, flush);
10027    }
10028
10029    @Override
10030    public boolean shutdown(int timeout) {
10031        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10032                != PackageManager.PERMISSION_GRANTED) {
10033            throw new SecurityException("Requires permission "
10034                    + android.Manifest.permission.SHUTDOWN);
10035        }
10036
10037        boolean timedout = false;
10038
10039        synchronized(this) {
10040            mShuttingDown = true;
10041            updateEventDispatchingLocked();
10042            timedout = mStackSupervisor.shutdownLocked(timeout);
10043        }
10044
10045        mAppOpsService.shutdown();
10046        if (mUsageStatsService != null) {
10047            mUsageStatsService.prepareShutdown();
10048        }
10049        mBatteryStatsService.shutdown();
10050        synchronized (this) {
10051            mProcessStats.shutdownLocked();
10052        }
10053        notifyTaskPersisterLocked(null, true);
10054
10055        return timedout;
10056    }
10057
10058    public final void activitySlept(IBinder token) {
10059        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10060
10061        final long origId = Binder.clearCallingIdentity();
10062
10063        synchronized (this) {
10064            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10065            if (r != null) {
10066                mStackSupervisor.activitySleptLocked(r);
10067            }
10068        }
10069
10070        Binder.restoreCallingIdentity(origId);
10071    }
10072
10073    void logLockScreen(String msg) {
10074        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10075                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10076                mWentToSleep + " mSleeping=" + mSleeping);
10077    }
10078
10079    private void comeOutOfSleepIfNeededLocked() {
10080        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10081            if (mSleeping) {
10082                mSleeping = false;
10083                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10084            }
10085        }
10086    }
10087
10088    void wakingUp() {
10089        synchronized(this) {
10090            mWentToSleep = false;
10091            comeOutOfSleepIfNeededLocked();
10092        }
10093    }
10094
10095    void startRunningVoiceLocked() {
10096        if (!mRunningVoice) {
10097            mRunningVoice = true;
10098            comeOutOfSleepIfNeededLocked();
10099        }
10100    }
10101
10102    private void updateEventDispatchingLocked() {
10103        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10104    }
10105
10106    public void setLockScreenShown(boolean shown) {
10107        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10108                != PackageManager.PERMISSION_GRANTED) {
10109            throw new SecurityException("Requires permission "
10110                    + android.Manifest.permission.DEVICE_POWER);
10111        }
10112
10113        synchronized(this) {
10114            long ident = Binder.clearCallingIdentity();
10115            try {
10116                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10117                mLockScreenShown = shown;
10118                comeOutOfSleepIfNeededLocked();
10119            } finally {
10120                Binder.restoreCallingIdentity(ident);
10121            }
10122        }
10123    }
10124
10125    @Override
10126    public void stopAppSwitches() {
10127        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10128                != PackageManager.PERMISSION_GRANTED) {
10129            throw new SecurityException("Requires permission "
10130                    + android.Manifest.permission.STOP_APP_SWITCHES);
10131        }
10132
10133        synchronized(this) {
10134            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10135                    + APP_SWITCH_DELAY_TIME;
10136            mDidAppSwitch = false;
10137            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10138            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10139            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10140        }
10141    }
10142
10143    public void resumeAppSwitches() {
10144        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10145                != PackageManager.PERMISSION_GRANTED) {
10146            throw new SecurityException("Requires permission "
10147                    + android.Manifest.permission.STOP_APP_SWITCHES);
10148        }
10149
10150        synchronized(this) {
10151            // Note that we don't execute any pending app switches... we will
10152            // let those wait until either the timeout, or the next start
10153            // activity request.
10154            mAppSwitchesAllowedTime = 0;
10155        }
10156    }
10157
10158    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10159            int callingPid, int callingUid, String name) {
10160        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10161            return true;
10162        }
10163
10164        int perm = checkComponentPermission(
10165                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10166                sourceUid, -1, true);
10167        if (perm == PackageManager.PERMISSION_GRANTED) {
10168            return true;
10169        }
10170
10171        // If the actual IPC caller is different from the logical source, then
10172        // also see if they are allowed to control app switches.
10173        if (callingUid != -1 && callingUid != sourceUid) {
10174            perm = checkComponentPermission(
10175                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10176                    callingUid, -1, true);
10177            if (perm == PackageManager.PERMISSION_GRANTED) {
10178                return true;
10179            }
10180        }
10181
10182        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10183        return false;
10184    }
10185
10186    public void setDebugApp(String packageName, boolean waitForDebugger,
10187            boolean persistent) {
10188        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10189                "setDebugApp()");
10190
10191        long ident = Binder.clearCallingIdentity();
10192        try {
10193            // Note that this is not really thread safe if there are multiple
10194            // callers into it at the same time, but that's not a situation we
10195            // care about.
10196            if (persistent) {
10197                final ContentResolver resolver = mContext.getContentResolver();
10198                Settings.Global.putString(
10199                    resolver, Settings.Global.DEBUG_APP,
10200                    packageName);
10201                Settings.Global.putInt(
10202                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10203                    waitForDebugger ? 1 : 0);
10204            }
10205
10206            synchronized (this) {
10207                if (!persistent) {
10208                    mOrigDebugApp = mDebugApp;
10209                    mOrigWaitForDebugger = mWaitForDebugger;
10210                }
10211                mDebugApp = packageName;
10212                mWaitForDebugger = waitForDebugger;
10213                mDebugTransient = !persistent;
10214                if (packageName != null) {
10215                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10216                            false, UserHandle.USER_ALL, "set debug app");
10217                }
10218            }
10219        } finally {
10220            Binder.restoreCallingIdentity(ident);
10221        }
10222    }
10223
10224    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10225        synchronized (this) {
10226            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10227            if (!isDebuggable) {
10228                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10229                    throw new SecurityException("Process not debuggable: " + app.packageName);
10230                }
10231            }
10232
10233            mOpenGlTraceApp = processName;
10234        }
10235    }
10236
10237    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10238        synchronized (this) {
10239            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10240            if (!isDebuggable) {
10241                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10242                    throw new SecurityException("Process not debuggable: " + app.packageName);
10243                }
10244            }
10245            mProfileApp = processName;
10246            mProfileFile = profilerInfo.profileFile;
10247            if (mProfileFd != null) {
10248                try {
10249                    mProfileFd.close();
10250                } catch (IOException e) {
10251                }
10252                mProfileFd = null;
10253            }
10254            mProfileFd = profilerInfo.profileFd;
10255            mSamplingInterval = profilerInfo.samplingInterval;
10256            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10257            mProfileType = 0;
10258        }
10259    }
10260
10261    @Override
10262    public void setAlwaysFinish(boolean enabled) {
10263        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10264                "setAlwaysFinish()");
10265
10266        Settings.Global.putInt(
10267                mContext.getContentResolver(),
10268                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10269
10270        synchronized (this) {
10271            mAlwaysFinishActivities = enabled;
10272        }
10273    }
10274
10275    @Override
10276    public void setActivityController(IActivityController controller) {
10277        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10278                "setActivityController()");
10279        synchronized (this) {
10280            mController = controller;
10281            Watchdog.getInstance().setActivityController(controller);
10282        }
10283    }
10284
10285    @Override
10286    public void setUserIsMonkey(boolean userIsMonkey) {
10287        synchronized (this) {
10288            synchronized (mPidsSelfLocked) {
10289                final int callingPid = Binder.getCallingPid();
10290                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10291                if (precessRecord == null) {
10292                    throw new SecurityException("Unknown process: " + callingPid);
10293                }
10294                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10295                    throw new SecurityException("Only an instrumentation process "
10296                            + "with a UiAutomation can call setUserIsMonkey");
10297                }
10298            }
10299            mUserIsMonkey = userIsMonkey;
10300        }
10301    }
10302
10303    @Override
10304    public boolean isUserAMonkey() {
10305        synchronized (this) {
10306            // If there is a controller also implies the user is a monkey.
10307            return (mUserIsMonkey || mController != null);
10308        }
10309    }
10310
10311    public void requestBugReport() {
10312        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10313        SystemProperties.set("ctl.start", "bugreport");
10314    }
10315
10316    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10317        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10318    }
10319
10320    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10321        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10322            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10323        }
10324        return KEY_DISPATCHING_TIMEOUT;
10325    }
10326
10327    @Override
10328    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10329        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10330                != PackageManager.PERMISSION_GRANTED) {
10331            throw new SecurityException("Requires permission "
10332                    + android.Manifest.permission.FILTER_EVENTS);
10333        }
10334        ProcessRecord proc;
10335        long timeout;
10336        synchronized (this) {
10337            synchronized (mPidsSelfLocked) {
10338                proc = mPidsSelfLocked.get(pid);
10339            }
10340            timeout = getInputDispatchingTimeoutLocked(proc);
10341        }
10342
10343        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10344            return -1;
10345        }
10346
10347        return timeout;
10348    }
10349
10350    /**
10351     * Handle input dispatching timeouts.
10352     * Returns whether input dispatching should be aborted or not.
10353     */
10354    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10355            final ActivityRecord activity, final ActivityRecord parent,
10356            final boolean aboveSystem, String reason) {
10357        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10358                != PackageManager.PERMISSION_GRANTED) {
10359            throw new SecurityException("Requires permission "
10360                    + android.Manifest.permission.FILTER_EVENTS);
10361        }
10362
10363        final String annotation;
10364        if (reason == null) {
10365            annotation = "Input dispatching timed out";
10366        } else {
10367            annotation = "Input dispatching timed out (" + reason + ")";
10368        }
10369
10370        if (proc != null) {
10371            synchronized (this) {
10372                if (proc.debugging) {
10373                    return false;
10374                }
10375
10376                if (mDidDexOpt) {
10377                    // Give more time since we were dexopting.
10378                    mDidDexOpt = false;
10379                    return false;
10380                }
10381
10382                if (proc.instrumentationClass != null) {
10383                    Bundle info = new Bundle();
10384                    info.putString("shortMsg", "keyDispatchingTimedOut");
10385                    info.putString("longMsg", annotation);
10386                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10387                    return true;
10388                }
10389            }
10390            mHandler.post(new Runnable() {
10391                @Override
10392                public void run() {
10393                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10394                }
10395            });
10396        }
10397
10398        return true;
10399    }
10400
10401    public Bundle getAssistContextExtras(int requestType) {
10402        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10403                "getAssistContextExtras()");
10404        PendingAssistExtras pae;
10405        Bundle extras = new Bundle();
10406        synchronized (this) {
10407            ActivityRecord activity = getFocusedStack().mResumedActivity;
10408            if (activity == null) {
10409                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10410                return null;
10411            }
10412            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10413            if (activity.app == null || activity.app.thread == null) {
10414                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10415                return extras;
10416            }
10417            if (activity.app.pid == Binder.getCallingPid()) {
10418                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10419                return extras;
10420            }
10421            pae = new PendingAssistExtras(activity);
10422            try {
10423                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10424                        requestType);
10425                mPendingAssistExtras.add(pae);
10426                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10427            } catch (RemoteException e) {
10428                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10429                return extras;
10430            }
10431        }
10432        synchronized (pae) {
10433            while (!pae.haveResult) {
10434                try {
10435                    pae.wait();
10436                } catch (InterruptedException e) {
10437                }
10438            }
10439            if (pae.result != null) {
10440                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10441            }
10442        }
10443        synchronized (this) {
10444            mPendingAssistExtras.remove(pae);
10445            mHandler.removeCallbacks(pae);
10446        }
10447        return extras;
10448    }
10449
10450    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10451        PendingAssistExtras pae = (PendingAssistExtras)token;
10452        synchronized (pae) {
10453            pae.result = extras;
10454            pae.haveResult = true;
10455            pae.notifyAll();
10456        }
10457    }
10458
10459    public void registerProcessObserver(IProcessObserver observer) {
10460        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10461                "registerProcessObserver()");
10462        synchronized (this) {
10463            mProcessObservers.register(observer);
10464        }
10465    }
10466
10467    @Override
10468    public void unregisterProcessObserver(IProcessObserver observer) {
10469        synchronized (this) {
10470            mProcessObservers.unregister(observer);
10471        }
10472    }
10473
10474    @Override
10475    public boolean convertFromTranslucent(IBinder token) {
10476        final long origId = Binder.clearCallingIdentity();
10477        try {
10478            synchronized (this) {
10479                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10480                if (r == null) {
10481                    return false;
10482                }
10483                final boolean translucentChanged = r.changeWindowTranslucency(true);
10484                if (translucentChanged) {
10485                    r.task.stack.releaseBackgroundResources();
10486                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10487                }
10488                mWindowManager.setAppFullscreen(token, true);
10489                return translucentChanged;
10490            }
10491        } finally {
10492            Binder.restoreCallingIdentity(origId);
10493        }
10494    }
10495
10496    @Override
10497    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10498        final long origId = Binder.clearCallingIdentity();
10499        try {
10500            synchronized (this) {
10501                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10502                if (r == null) {
10503                    return false;
10504                }
10505                int index = r.task.mActivities.lastIndexOf(r);
10506                if (index > 0) {
10507                    ActivityRecord under = r.task.mActivities.get(index - 1);
10508                    under.returningOptions = options;
10509                }
10510                final boolean translucentChanged = r.changeWindowTranslucency(false);
10511                if (translucentChanged) {
10512                    r.task.stack.convertToTranslucent(r);
10513                }
10514                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10515                mWindowManager.setAppFullscreen(token, false);
10516                return translucentChanged;
10517            }
10518        } finally {
10519            Binder.restoreCallingIdentity(origId);
10520        }
10521    }
10522
10523    @Override
10524    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10525        final long origId = Binder.clearCallingIdentity();
10526        try {
10527            synchronized (this) {
10528                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10529                if (r != null) {
10530                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10531                }
10532            }
10533            return false;
10534        } finally {
10535            Binder.restoreCallingIdentity(origId);
10536        }
10537    }
10538
10539    @Override
10540    public boolean isBackgroundVisibleBehind(IBinder token) {
10541        final long origId = Binder.clearCallingIdentity();
10542        try {
10543            synchronized (this) {
10544                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10545                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10546                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10547                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10548                return visible;
10549            }
10550        } finally {
10551            Binder.restoreCallingIdentity(origId);
10552        }
10553    }
10554
10555    @Override
10556    public ActivityOptions getActivityOptions(IBinder token) {
10557        final long origId = Binder.clearCallingIdentity();
10558        try {
10559            synchronized (this) {
10560                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10561                if (r != null) {
10562                    final ActivityOptions activityOptions = r.pendingOptions;
10563                    r.pendingOptions = null;
10564                    return activityOptions;
10565                }
10566                return null;
10567            }
10568        } finally {
10569            Binder.restoreCallingIdentity(origId);
10570        }
10571    }
10572
10573    @Override
10574    public void setImmersive(IBinder token, boolean immersive) {
10575        synchronized(this) {
10576            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10577            if (r == null) {
10578                throw new IllegalArgumentException();
10579            }
10580            r.immersive = immersive;
10581
10582            // update associated state if we're frontmost
10583            if (r == mFocusedActivity) {
10584                if (DEBUG_IMMERSIVE) {
10585                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10586                }
10587                applyUpdateLockStateLocked(r);
10588            }
10589        }
10590    }
10591
10592    @Override
10593    public boolean isImmersive(IBinder token) {
10594        synchronized (this) {
10595            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10596            if (r == null) {
10597                throw new IllegalArgumentException();
10598            }
10599            return r.immersive;
10600        }
10601    }
10602
10603    public boolean isTopActivityImmersive() {
10604        enforceNotIsolatedCaller("startActivity");
10605        synchronized (this) {
10606            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10607            return (r != null) ? r.immersive : false;
10608        }
10609    }
10610
10611    @Override
10612    public boolean isTopOfTask(IBinder token) {
10613        synchronized (this) {
10614            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10615            if (r == null) {
10616                throw new IllegalArgumentException();
10617            }
10618            return r.task.getTopActivity() == r;
10619        }
10620    }
10621
10622    public final void enterSafeMode() {
10623        synchronized(this) {
10624            // It only makes sense to do this before the system is ready
10625            // and started launching other packages.
10626            if (!mSystemReady) {
10627                try {
10628                    AppGlobals.getPackageManager().enterSafeMode();
10629                } catch (RemoteException e) {
10630                }
10631            }
10632
10633            mSafeMode = true;
10634        }
10635    }
10636
10637    public final void showSafeModeOverlay() {
10638        View v = LayoutInflater.from(mContext).inflate(
10639                com.android.internal.R.layout.safe_mode, null);
10640        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10641        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10642        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10643        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10644        lp.gravity = Gravity.BOTTOM | Gravity.START;
10645        lp.format = v.getBackground().getOpacity();
10646        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10647                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10648        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10649        ((WindowManager)mContext.getSystemService(
10650                Context.WINDOW_SERVICE)).addView(v, lp);
10651    }
10652
10653    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10654        if (!(sender instanceof PendingIntentRecord)) {
10655            return;
10656        }
10657        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10658        synchronized (stats) {
10659            if (mBatteryStatsService.isOnBattery()) {
10660                mBatteryStatsService.enforceCallingPermission();
10661                PendingIntentRecord rec = (PendingIntentRecord)sender;
10662                int MY_UID = Binder.getCallingUid();
10663                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10664                BatteryStatsImpl.Uid.Pkg pkg =
10665                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10666                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10667                pkg.incWakeupsLocked();
10668            }
10669        }
10670    }
10671
10672    public boolean killPids(int[] pids, String pReason, boolean secure) {
10673        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10674            throw new SecurityException("killPids only available to the system");
10675        }
10676        String reason = (pReason == null) ? "Unknown" : pReason;
10677        // XXX Note: don't acquire main activity lock here, because the window
10678        // manager calls in with its locks held.
10679
10680        boolean killed = false;
10681        synchronized (mPidsSelfLocked) {
10682            int[] types = new int[pids.length];
10683            int worstType = 0;
10684            for (int i=0; i<pids.length; i++) {
10685                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10686                if (proc != null) {
10687                    int type = proc.setAdj;
10688                    types[i] = type;
10689                    if (type > worstType) {
10690                        worstType = type;
10691                    }
10692                }
10693            }
10694
10695            // If the worst oom_adj is somewhere in the cached proc LRU range,
10696            // then constrain it so we will kill all cached procs.
10697            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10698                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10699                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10700            }
10701
10702            // If this is not a secure call, don't let it kill processes that
10703            // are important.
10704            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10705                worstType = ProcessList.SERVICE_ADJ;
10706            }
10707
10708            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10709            for (int i=0; i<pids.length; i++) {
10710                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10711                if (proc == null) {
10712                    continue;
10713                }
10714                int adj = proc.setAdj;
10715                if (adj >= worstType && !proc.killedByAm) {
10716                    proc.kill(reason, true);
10717                    killed = true;
10718                }
10719            }
10720        }
10721        return killed;
10722    }
10723
10724    @Override
10725    public void killUid(int uid, String reason) {
10726        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10727            throw new SecurityException("killUid only available to the system");
10728        }
10729        synchronized (this) {
10730            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10731                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10732                    reason != null ? reason : "kill uid");
10733        }
10734    }
10735
10736    @Override
10737    public boolean killProcessesBelowForeground(String reason) {
10738        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10739            throw new SecurityException("killProcessesBelowForeground() only available to system");
10740        }
10741
10742        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10743    }
10744
10745    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10746        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10747            throw new SecurityException("killProcessesBelowAdj() only available to system");
10748        }
10749
10750        boolean killed = false;
10751        synchronized (mPidsSelfLocked) {
10752            final int size = mPidsSelfLocked.size();
10753            for (int i = 0; i < size; i++) {
10754                final int pid = mPidsSelfLocked.keyAt(i);
10755                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10756                if (proc == null) continue;
10757
10758                final int adj = proc.setAdj;
10759                if (adj > belowAdj && !proc.killedByAm) {
10760                    proc.kill(reason, true);
10761                    killed = true;
10762                }
10763            }
10764        }
10765        return killed;
10766    }
10767
10768    @Override
10769    public void hang(final IBinder who, boolean allowRestart) {
10770        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10771                != PackageManager.PERMISSION_GRANTED) {
10772            throw new SecurityException("Requires permission "
10773                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10774        }
10775
10776        final IBinder.DeathRecipient death = new DeathRecipient() {
10777            @Override
10778            public void binderDied() {
10779                synchronized (this) {
10780                    notifyAll();
10781                }
10782            }
10783        };
10784
10785        try {
10786            who.linkToDeath(death, 0);
10787        } catch (RemoteException e) {
10788            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10789            return;
10790        }
10791
10792        synchronized (this) {
10793            Watchdog.getInstance().setAllowRestart(allowRestart);
10794            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10795            synchronized (death) {
10796                while (who.isBinderAlive()) {
10797                    try {
10798                        death.wait();
10799                    } catch (InterruptedException e) {
10800                    }
10801                }
10802            }
10803            Watchdog.getInstance().setAllowRestart(true);
10804        }
10805    }
10806
10807    @Override
10808    public void restart() {
10809        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10810                != PackageManager.PERMISSION_GRANTED) {
10811            throw new SecurityException("Requires permission "
10812                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10813        }
10814
10815        Log.i(TAG, "Sending shutdown broadcast...");
10816
10817        BroadcastReceiver br = new BroadcastReceiver() {
10818            @Override public void onReceive(Context context, Intent intent) {
10819                // Now the broadcast is done, finish up the low-level shutdown.
10820                Log.i(TAG, "Shutting down activity manager...");
10821                shutdown(10000);
10822                Log.i(TAG, "Shutdown complete, restarting!");
10823                Process.killProcess(Process.myPid());
10824                System.exit(10);
10825            }
10826        };
10827
10828        // First send the high-level shut down broadcast.
10829        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10830        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10831        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10832        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10833        mContext.sendOrderedBroadcastAsUser(intent,
10834                UserHandle.ALL, null, br, mHandler, 0, null, null);
10835        */
10836        br.onReceive(mContext, intent);
10837    }
10838
10839    private long getLowRamTimeSinceIdle(long now) {
10840        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10841    }
10842
10843    @Override
10844    public void performIdleMaintenance() {
10845        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10846                != PackageManager.PERMISSION_GRANTED) {
10847            throw new SecurityException("Requires permission "
10848                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10849        }
10850
10851        synchronized (this) {
10852            final long now = SystemClock.uptimeMillis();
10853            final long timeSinceLastIdle = now - mLastIdleTime;
10854            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10855            mLastIdleTime = now;
10856            mLowRamTimeSinceLastIdle = 0;
10857            if (mLowRamStartTime != 0) {
10858                mLowRamStartTime = now;
10859            }
10860
10861            StringBuilder sb = new StringBuilder(128);
10862            sb.append("Idle maintenance over ");
10863            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10864            sb.append(" low RAM for ");
10865            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10866            Slog.i(TAG, sb.toString());
10867
10868            // If at least 1/3 of our time since the last idle period has been spent
10869            // with RAM low, then we want to kill processes.
10870            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10871
10872            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10873                ProcessRecord proc = mLruProcesses.get(i);
10874                if (proc.notCachedSinceIdle) {
10875                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10876                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10877                        if (doKilling && proc.initialIdlePss != 0
10878                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10879                            proc.kill("idle maint (pss " + proc.lastPss
10880                                    + " from " + proc.initialIdlePss + ")", true);
10881                        }
10882                    }
10883                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10884                    proc.notCachedSinceIdle = true;
10885                    proc.initialIdlePss = 0;
10886                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10887                            isSleeping(), now);
10888                }
10889            }
10890
10891            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10892            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10893        }
10894    }
10895
10896    private void retrieveSettings() {
10897        final ContentResolver resolver = mContext.getContentResolver();
10898        String debugApp = Settings.Global.getString(
10899            resolver, Settings.Global.DEBUG_APP);
10900        boolean waitForDebugger = Settings.Global.getInt(
10901            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10902        boolean alwaysFinishActivities = Settings.Global.getInt(
10903            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10904        boolean forceRtl = Settings.Global.getInt(
10905                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10906        // Transfer any global setting for forcing RTL layout, into a System Property
10907        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10908
10909        Configuration configuration = new Configuration();
10910        Settings.System.getConfiguration(resolver, configuration);
10911        if (forceRtl) {
10912            // This will take care of setting the correct layout direction flags
10913            configuration.setLayoutDirection(configuration.locale);
10914        }
10915
10916        synchronized (this) {
10917            mDebugApp = mOrigDebugApp = debugApp;
10918            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10919            mAlwaysFinishActivities = alwaysFinishActivities;
10920            // This happens before any activities are started, so we can
10921            // change mConfiguration in-place.
10922            updateConfigurationLocked(configuration, null, false, true);
10923            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10924        }
10925    }
10926
10927    /** Loads resources after the current configuration has been set. */
10928    private void loadResourcesOnSystemReady() {
10929        final Resources res = mContext.getResources();
10930        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10931        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10932        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10933    }
10934
10935    public boolean testIsSystemReady() {
10936        // no need to synchronize(this) just to read & return the value
10937        return mSystemReady;
10938    }
10939
10940    private static File getCalledPreBootReceiversFile() {
10941        File dataDir = Environment.getDataDirectory();
10942        File systemDir = new File(dataDir, "system");
10943        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10944        return fname;
10945    }
10946
10947    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10948        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10949        File file = getCalledPreBootReceiversFile();
10950        FileInputStream fis = null;
10951        try {
10952            fis = new FileInputStream(file);
10953            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10954            int fvers = dis.readInt();
10955            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10956                String vers = dis.readUTF();
10957                String codename = dis.readUTF();
10958                String build = dis.readUTF();
10959                if (android.os.Build.VERSION.RELEASE.equals(vers)
10960                        && android.os.Build.VERSION.CODENAME.equals(codename)
10961                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10962                    int num = dis.readInt();
10963                    while (num > 0) {
10964                        num--;
10965                        String pkg = dis.readUTF();
10966                        String cls = dis.readUTF();
10967                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10968                    }
10969                }
10970            }
10971        } catch (FileNotFoundException e) {
10972        } catch (IOException e) {
10973            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10974        } finally {
10975            if (fis != null) {
10976                try {
10977                    fis.close();
10978                } catch (IOException e) {
10979                }
10980            }
10981        }
10982        return lastDoneReceivers;
10983    }
10984
10985    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10986        File file = getCalledPreBootReceiversFile();
10987        FileOutputStream fos = null;
10988        DataOutputStream dos = null;
10989        try {
10990            fos = new FileOutputStream(file);
10991            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10992            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10993            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10994            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10995            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10996            dos.writeInt(list.size());
10997            for (int i=0; i<list.size(); i++) {
10998                dos.writeUTF(list.get(i).getPackageName());
10999                dos.writeUTF(list.get(i).getClassName());
11000            }
11001        } catch (IOException e) {
11002            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11003            file.delete();
11004        } finally {
11005            FileUtils.sync(fos);
11006            if (dos != null) {
11007                try {
11008                    dos.close();
11009                } catch (IOException e) {
11010                    // TODO Auto-generated catch block
11011                    e.printStackTrace();
11012                }
11013            }
11014        }
11015    }
11016
11017    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11018            ArrayList<ComponentName> doneReceivers, int userId) {
11019        boolean waitingUpdate = false;
11020        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11021        List<ResolveInfo> ris = null;
11022        try {
11023            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11024                    intent, null, 0, userId);
11025        } catch (RemoteException e) {
11026        }
11027        if (ris != null) {
11028            for (int i=ris.size()-1; i>=0; i--) {
11029                if ((ris.get(i).activityInfo.applicationInfo.flags
11030                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11031                    ris.remove(i);
11032                }
11033            }
11034            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11035
11036            // For User 0, load the version number. When delivering to a new user, deliver
11037            // to all receivers.
11038            if (userId == UserHandle.USER_OWNER) {
11039                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11040                for (int i=0; i<ris.size(); i++) {
11041                    ActivityInfo ai = ris.get(i).activityInfo;
11042                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11043                    if (lastDoneReceivers.contains(comp)) {
11044                        // We already did the pre boot receiver for this app with the current
11045                        // platform version, so don't do it again...
11046                        ris.remove(i);
11047                        i--;
11048                        // ...however, do keep it as one that has been done, so we don't
11049                        // forget about it when rewriting the file of last done receivers.
11050                        doneReceivers.add(comp);
11051                    }
11052                }
11053            }
11054
11055            // If primary user, send broadcast to all available users, else just to userId
11056            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11057                    : new int[] { userId };
11058            for (int i = 0; i < ris.size(); i++) {
11059                ActivityInfo ai = ris.get(i).activityInfo;
11060                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11061                doneReceivers.add(comp);
11062                intent.setComponent(comp);
11063                for (int j=0; j<users.length; j++) {
11064                    IIntentReceiver finisher = null;
11065                    // On last receiver and user, set up a completion callback
11066                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11067                        finisher = new IIntentReceiver.Stub() {
11068                            public void performReceive(Intent intent, int resultCode,
11069                                    String data, Bundle extras, boolean ordered,
11070                                    boolean sticky, int sendingUser) {
11071                                // The raw IIntentReceiver interface is called
11072                                // with the AM lock held, so redispatch to
11073                                // execute our code without the lock.
11074                                mHandler.post(onFinishCallback);
11075                            }
11076                        };
11077                    }
11078                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11079                            + " for user " + users[j]);
11080                    broadcastIntentLocked(null, null, intent, null, finisher,
11081                            0, null, null, null, AppOpsManager.OP_NONE,
11082                            true, false, MY_PID, Process.SYSTEM_UID,
11083                            users[j]);
11084                    if (finisher != null) {
11085                        waitingUpdate = true;
11086                    }
11087                }
11088            }
11089        }
11090
11091        return waitingUpdate;
11092    }
11093
11094    public void systemReady(final Runnable goingCallback) {
11095        synchronized(this) {
11096            if (mSystemReady) {
11097                // If we're done calling all the receivers, run the next "boot phase" passed in
11098                // by the SystemServer
11099                if (goingCallback != null) {
11100                    goingCallback.run();
11101                }
11102                return;
11103            }
11104
11105            // Make sure we have the current profile info, since it is needed for
11106            // security checks.
11107            updateCurrentProfileIdsLocked();
11108
11109            if (mRecentTasks == null) {
11110                mRecentTasks = mTaskPersister.restoreTasksLocked();
11111                if (!mRecentTasks.isEmpty()) {
11112                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11113                }
11114                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11115                mTaskPersister.startPersisting();
11116            }
11117
11118            // Check to see if there are any update receivers to run.
11119            if (!mDidUpdate) {
11120                if (mWaitingUpdate) {
11121                    return;
11122                }
11123                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11124                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11125                    public void run() {
11126                        synchronized (ActivityManagerService.this) {
11127                            mDidUpdate = true;
11128                        }
11129                        writeLastDonePreBootReceivers(doneReceivers);
11130                        showBootMessage(mContext.getText(
11131                                R.string.android_upgrading_complete),
11132                                false);
11133                        systemReady(goingCallback);
11134                    }
11135                }, doneReceivers, UserHandle.USER_OWNER);
11136
11137                if (mWaitingUpdate) {
11138                    return;
11139                }
11140                mDidUpdate = true;
11141            }
11142
11143            mAppOpsService.systemReady();
11144            mSystemReady = true;
11145        }
11146
11147        ArrayList<ProcessRecord> procsToKill = null;
11148        synchronized(mPidsSelfLocked) {
11149            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11150                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11151                if (!isAllowedWhileBooting(proc.info)){
11152                    if (procsToKill == null) {
11153                        procsToKill = new ArrayList<ProcessRecord>();
11154                    }
11155                    procsToKill.add(proc);
11156                }
11157            }
11158        }
11159
11160        synchronized(this) {
11161            if (procsToKill != null) {
11162                for (int i=procsToKill.size()-1; i>=0; i--) {
11163                    ProcessRecord proc = procsToKill.get(i);
11164                    Slog.i(TAG, "Removing system update proc: " + proc);
11165                    removeProcessLocked(proc, true, false, "system update done");
11166                }
11167            }
11168
11169            // Now that we have cleaned up any update processes, we
11170            // are ready to start launching real processes and know that
11171            // we won't trample on them any more.
11172            mProcessesReady = true;
11173        }
11174
11175        Slog.i(TAG, "System now ready");
11176        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11177            SystemClock.uptimeMillis());
11178
11179        synchronized(this) {
11180            // Make sure we have no pre-ready processes sitting around.
11181
11182            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11183                ResolveInfo ri = mContext.getPackageManager()
11184                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11185                                STOCK_PM_FLAGS);
11186                CharSequence errorMsg = null;
11187                if (ri != null) {
11188                    ActivityInfo ai = ri.activityInfo;
11189                    ApplicationInfo app = ai.applicationInfo;
11190                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11191                        mTopAction = Intent.ACTION_FACTORY_TEST;
11192                        mTopData = null;
11193                        mTopComponent = new ComponentName(app.packageName,
11194                                ai.name);
11195                    } else {
11196                        errorMsg = mContext.getResources().getText(
11197                                com.android.internal.R.string.factorytest_not_system);
11198                    }
11199                } else {
11200                    errorMsg = mContext.getResources().getText(
11201                            com.android.internal.R.string.factorytest_no_action);
11202                }
11203                if (errorMsg != null) {
11204                    mTopAction = null;
11205                    mTopData = null;
11206                    mTopComponent = null;
11207                    Message msg = Message.obtain();
11208                    msg.what = SHOW_FACTORY_ERROR_MSG;
11209                    msg.getData().putCharSequence("msg", errorMsg);
11210                    mHandler.sendMessage(msg);
11211                }
11212            }
11213        }
11214
11215        retrieveSettings();
11216        loadResourcesOnSystemReady();
11217
11218        synchronized (this) {
11219            readGrantedUriPermissionsLocked();
11220        }
11221
11222        if (goingCallback != null) goingCallback.run();
11223
11224        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11225                Integer.toString(mCurrentUserId), mCurrentUserId);
11226        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11227                Integer.toString(mCurrentUserId), mCurrentUserId);
11228        mSystemServiceManager.startUser(mCurrentUserId);
11229
11230        synchronized (this) {
11231            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11232                try {
11233                    List apps = AppGlobals.getPackageManager().
11234                        getPersistentApplications(STOCK_PM_FLAGS);
11235                    if (apps != null) {
11236                        int N = apps.size();
11237                        int i;
11238                        for (i=0; i<N; i++) {
11239                            ApplicationInfo info
11240                                = (ApplicationInfo)apps.get(i);
11241                            if (info != null &&
11242                                    !info.packageName.equals("android")) {
11243                                addAppLocked(info, false, null /* ABI override */);
11244                            }
11245                        }
11246                    }
11247                } catch (RemoteException ex) {
11248                    // pm is in same process, this will never happen.
11249                }
11250            }
11251
11252            // Start up initial activity.
11253            mBooting = true;
11254
11255            try {
11256                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11257                    Message msg = Message.obtain();
11258                    msg.what = SHOW_UID_ERROR_MSG;
11259                    mHandler.sendMessage(msg);
11260                }
11261            } catch (RemoteException e) {
11262            }
11263
11264            long ident = Binder.clearCallingIdentity();
11265            try {
11266                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11267                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11268                        | Intent.FLAG_RECEIVER_FOREGROUND);
11269                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11270                broadcastIntentLocked(null, null, intent,
11271                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11272                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11273                intent = new Intent(Intent.ACTION_USER_STARTING);
11274                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11275                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11276                broadcastIntentLocked(null, null, intent,
11277                        null, new IIntentReceiver.Stub() {
11278                            @Override
11279                            public void performReceive(Intent intent, int resultCode, String data,
11280                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11281                                    throws RemoteException {
11282                            }
11283                        }, 0, null, null,
11284                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11285                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11286            } catch (Throwable t) {
11287                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11288            } finally {
11289                Binder.restoreCallingIdentity(ident);
11290            }
11291            mStackSupervisor.resumeTopActivitiesLocked();
11292            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11293        }
11294    }
11295
11296    private boolean makeAppCrashingLocked(ProcessRecord app,
11297            String shortMsg, String longMsg, String stackTrace) {
11298        app.crashing = true;
11299        app.crashingReport = generateProcessError(app,
11300                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11301        startAppProblemLocked(app);
11302        app.stopFreezingAllLocked();
11303        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11304    }
11305
11306    private void makeAppNotRespondingLocked(ProcessRecord app,
11307            String activity, String shortMsg, String longMsg) {
11308        app.notResponding = true;
11309        app.notRespondingReport = generateProcessError(app,
11310                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11311                activity, shortMsg, longMsg, null);
11312        startAppProblemLocked(app);
11313        app.stopFreezingAllLocked();
11314    }
11315
11316    /**
11317     * Generate a process error record, suitable for attachment to a ProcessRecord.
11318     *
11319     * @param app The ProcessRecord in which the error occurred.
11320     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11321     *                      ActivityManager.AppErrorStateInfo
11322     * @param activity The activity associated with the crash, if known.
11323     * @param shortMsg Short message describing the crash.
11324     * @param longMsg Long message describing the crash.
11325     * @param stackTrace Full crash stack trace, may be null.
11326     *
11327     * @return Returns a fully-formed AppErrorStateInfo record.
11328     */
11329    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11330            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11331        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11332
11333        report.condition = condition;
11334        report.processName = app.processName;
11335        report.pid = app.pid;
11336        report.uid = app.info.uid;
11337        report.tag = activity;
11338        report.shortMsg = shortMsg;
11339        report.longMsg = longMsg;
11340        report.stackTrace = stackTrace;
11341
11342        return report;
11343    }
11344
11345    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11346        synchronized (this) {
11347            app.crashing = false;
11348            app.crashingReport = null;
11349            app.notResponding = false;
11350            app.notRespondingReport = null;
11351            if (app.anrDialog == fromDialog) {
11352                app.anrDialog = null;
11353            }
11354            if (app.waitDialog == fromDialog) {
11355                app.waitDialog = null;
11356            }
11357            if (app.pid > 0 && app.pid != MY_PID) {
11358                handleAppCrashLocked(app, null, null, null);
11359                app.kill("user request after error", true);
11360            }
11361        }
11362    }
11363
11364    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11365            String stackTrace) {
11366        long now = SystemClock.uptimeMillis();
11367
11368        Long crashTime;
11369        if (!app.isolated) {
11370            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11371        } else {
11372            crashTime = null;
11373        }
11374        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11375            // This process loses!
11376            Slog.w(TAG, "Process " + app.info.processName
11377                    + " has crashed too many times: killing!");
11378            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11379                    app.userId, app.info.processName, app.uid);
11380            mStackSupervisor.handleAppCrashLocked(app);
11381            if (!app.persistent) {
11382                // We don't want to start this process again until the user
11383                // explicitly does so...  but for persistent process, we really
11384                // need to keep it running.  If a persistent process is actually
11385                // repeatedly crashing, then badness for everyone.
11386                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11387                        app.info.processName);
11388                if (!app.isolated) {
11389                    // XXX We don't have a way to mark isolated processes
11390                    // as bad, since they don't have a peristent identity.
11391                    mBadProcesses.put(app.info.processName, app.uid,
11392                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11393                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11394                }
11395                app.bad = true;
11396                app.removed = true;
11397                // Don't let services in this process be restarted and potentially
11398                // annoy the user repeatedly.  Unless it is persistent, since those
11399                // processes run critical code.
11400                removeProcessLocked(app, false, false, "crash");
11401                mStackSupervisor.resumeTopActivitiesLocked();
11402                return false;
11403            }
11404            mStackSupervisor.resumeTopActivitiesLocked();
11405        } else {
11406            mStackSupervisor.finishTopRunningActivityLocked(app);
11407        }
11408
11409        // Bump up the crash count of any services currently running in the proc.
11410        for (int i=app.services.size()-1; i>=0; i--) {
11411            // Any services running in the application need to be placed
11412            // back in the pending list.
11413            ServiceRecord sr = app.services.valueAt(i);
11414            sr.crashCount++;
11415        }
11416
11417        // If the crashing process is what we consider to be the "home process" and it has been
11418        // replaced by a third-party app, clear the package preferred activities from packages
11419        // with a home activity running in the process to prevent a repeatedly crashing app
11420        // from blocking the user to manually clear the list.
11421        final ArrayList<ActivityRecord> activities = app.activities;
11422        if (app == mHomeProcess && activities.size() > 0
11423                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11424            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11425                final ActivityRecord r = activities.get(activityNdx);
11426                if (r.isHomeActivity()) {
11427                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11428                    try {
11429                        ActivityThread.getPackageManager()
11430                                .clearPackagePreferredActivities(r.packageName);
11431                    } catch (RemoteException c) {
11432                        // pm is in same process, this will never happen.
11433                    }
11434                }
11435            }
11436        }
11437
11438        if (!app.isolated) {
11439            // XXX Can't keep track of crash times for isolated processes,
11440            // because they don't have a perisistent identity.
11441            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11442        }
11443
11444        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11445        return true;
11446    }
11447
11448    void startAppProblemLocked(ProcessRecord app) {
11449        // If this app is not running under the current user, then we
11450        // can't give it a report button because that would require
11451        // launching the report UI under a different user.
11452        app.errorReportReceiver = null;
11453
11454        for (int userId : mCurrentProfileIds) {
11455            if (app.userId == userId) {
11456                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11457                        mContext, app.info.packageName, app.info.flags);
11458            }
11459        }
11460        skipCurrentReceiverLocked(app);
11461    }
11462
11463    void skipCurrentReceiverLocked(ProcessRecord app) {
11464        for (BroadcastQueue queue : mBroadcastQueues) {
11465            queue.skipCurrentReceiverLocked(app);
11466        }
11467    }
11468
11469    /**
11470     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11471     * The application process will exit immediately after this call returns.
11472     * @param app object of the crashing app, null for the system server
11473     * @param crashInfo describing the exception
11474     */
11475    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11476        ProcessRecord r = findAppProcess(app, "Crash");
11477        final String processName = app == null ? "system_server"
11478                : (r == null ? "unknown" : r.processName);
11479
11480        handleApplicationCrashInner("crash", r, processName, crashInfo);
11481    }
11482
11483    /* Native crash reporting uses this inner version because it needs to be somewhat
11484     * decoupled from the AM-managed cleanup lifecycle
11485     */
11486    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11487            ApplicationErrorReport.CrashInfo crashInfo) {
11488        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11489                UserHandle.getUserId(Binder.getCallingUid()), processName,
11490                r == null ? -1 : r.info.flags,
11491                crashInfo.exceptionClassName,
11492                crashInfo.exceptionMessage,
11493                crashInfo.throwFileName,
11494                crashInfo.throwLineNumber);
11495
11496        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11497
11498        crashApplication(r, crashInfo);
11499    }
11500
11501    public void handleApplicationStrictModeViolation(
11502            IBinder app,
11503            int violationMask,
11504            StrictMode.ViolationInfo info) {
11505        ProcessRecord r = findAppProcess(app, "StrictMode");
11506        if (r == null) {
11507            return;
11508        }
11509
11510        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11511            Integer stackFingerprint = info.hashCode();
11512            boolean logIt = true;
11513            synchronized (mAlreadyLoggedViolatedStacks) {
11514                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11515                    logIt = false;
11516                    // TODO: sub-sample into EventLog for these, with
11517                    // the info.durationMillis?  Then we'd get
11518                    // the relative pain numbers, without logging all
11519                    // the stack traces repeatedly.  We'd want to do
11520                    // likewise in the client code, which also does
11521                    // dup suppression, before the Binder call.
11522                } else {
11523                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11524                        mAlreadyLoggedViolatedStacks.clear();
11525                    }
11526                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11527                }
11528            }
11529            if (logIt) {
11530                logStrictModeViolationToDropBox(r, info);
11531            }
11532        }
11533
11534        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11535            AppErrorResult result = new AppErrorResult();
11536            synchronized (this) {
11537                final long origId = Binder.clearCallingIdentity();
11538
11539                Message msg = Message.obtain();
11540                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11541                HashMap<String, Object> data = new HashMap<String, Object>();
11542                data.put("result", result);
11543                data.put("app", r);
11544                data.put("violationMask", violationMask);
11545                data.put("info", info);
11546                msg.obj = data;
11547                mHandler.sendMessage(msg);
11548
11549                Binder.restoreCallingIdentity(origId);
11550            }
11551            int res = result.get();
11552            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11553        }
11554    }
11555
11556    // Depending on the policy in effect, there could be a bunch of
11557    // these in quick succession so we try to batch these together to
11558    // minimize disk writes, number of dropbox entries, and maximize
11559    // compression, by having more fewer, larger records.
11560    private void logStrictModeViolationToDropBox(
11561            ProcessRecord process,
11562            StrictMode.ViolationInfo info) {
11563        if (info == null) {
11564            return;
11565        }
11566        final boolean isSystemApp = process == null ||
11567                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11568                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11569        final String processName = process == null ? "unknown" : process.processName;
11570        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11571        final DropBoxManager dbox = (DropBoxManager)
11572                mContext.getSystemService(Context.DROPBOX_SERVICE);
11573
11574        // Exit early if the dropbox isn't configured to accept this report type.
11575        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11576
11577        boolean bufferWasEmpty;
11578        boolean needsFlush;
11579        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11580        synchronized (sb) {
11581            bufferWasEmpty = sb.length() == 0;
11582            appendDropBoxProcessHeaders(process, processName, sb);
11583            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11584            sb.append("System-App: ").append(isSystemApp).append("\n");
11585            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11586            if (info.violationNumThisLoop != 0) {
11587                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11588            }
11589            if (info.numAnimationsRunning != 0) {
11590                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11591            }
11592            if (info.broadcastIntentAction != null) {
11593                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11594            }
11595            if (info.durationMillis != -1) {
11596                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11597            }
11598            if (info.numInstances != -1) {
11599                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11600            }
11601            if (info.tags != null) {
11602                for (String tag : info.tags) {
11603                    sb.append("Span-Tag: ").append(tag).append("\n");
11604                }
11605            }
11606            sb.append("\n");
11607            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11608                sb.append(info.crashInfo.stackTrace);
11609            }
11610            sb.append("\n");
11611
11612            // Only buffer up to ~64k.  Various logging bits truncate
11613            // things at 128k.
11614            needsFlush = (sb.length() > 64 * 1024);
11615        }
11616
11617        // Flush immediately if the buffer's grown too large, or this
11618        // is a non-system app.  Non-system apps are isolated with a
11619        // different tag & policy and not batched.
11620        //
11621        // Batching is useful during internal testing with
11622        // StrictMode settings turned up high.  Without batching,
11623        // thousands of separate files could be created on boot.
11624        if (!isSystemApp || needsFlush) {
11625            new Thread("Error dump: " + dropboxTag) {
11626                @Override
11627                public void run() {
11628                    String report;
11629                    synchronized (sb) {
11630                        report = sb.toString();
11631                        sb.delete(0, sb.length());
11632                        sb.trimToSize();
11633                    }
11634                    if (report.length() != 0) {
11635                        dbox.addText(dropboxTag, report);
11636                    }
11637                }
11638            }.start();
11639            return;
11640        }
11641
11642        // System app batching:
11643        if (!bufferWasEmpty) {
11644            // An existing dropbox-writing thread is outstanding, so
11645            // we don't need to start it up.  The existing thread will
11646            // catch the buffer appends we just did.
11647            return;
11648        }
11649
11650        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11651        // (After this point, we shouldn't access AMS internal data structures.)
11652        new Thread("Error dump: " + dropboxTag) {
11653            @Override
11654            public void run() {
11655                // 5 second sleep to let stacks arrive and be batched together
11656                try {
11657                    Thread.sleep(5000);  // 5 seconds
11658                } catch (InterruptedException e) {}
11659
11660                String errorReport;
11661                synchronized (mStrictModeBuffer) {
11662                    errorReport = mStrictModeBuffer.toString();
11663                    if (errorReport.length() == 0) {
11664                        return;
11665                    }
11666                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11667                    mStrictModeBuffer.trimToSize();
11668                }
11669                dbox.addText(dropboxTag, errorReport);
11670            }
11671        }.start();
11672    }
11673
11674    /**
11675     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11676     * @param app object of the crashing app, null for the system server
11677     * @param tag reported by the caller
11678     * @param system whether this wtf is coming from the system
11679     * @param crashInfo describing the context of the error
11680     * @return true if the process should exit immediately (WTF is fatal)
11681     */
11682    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11683            final ApplicationErrorReport.CrashInfo crashInfo) {
11684        final ProcessRecord r = findAppProcess(app, "WTF");
11685        final String processName = app == null ? "system_server"
11686                : (r == null ? "unknown" : r.processName);
11687
11688        EventLog.writeEvent(EventLogTags.AM_WTF,
11689                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11690                processName,
11691                r == null ? -1 : r.info.flags,
11692                tag, crashInfo.exceptionMessage);
11693
11694        if (system) {
11695            // If this is coming from the system, we could very well have low-level
11696            // system locks held, so we want to do this all asynchronously.  And we
11697            // never want this to become fatal, so there is that too.
11698            mHandler.post(new Runnable() {
11699                @Override public void run() {
11700                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11701                            crashInfo);
11702                }
11703            });
11704            return false;
11705        }
11706
11707        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11708
11709        if (r != null && r.pid != Process.myPid() &&
11710                Settings.Global.getInt(mContext.getContentResolver(),
11711                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11712            crashApplication(r, crashInfo);
11713            return true;
11714        } else {
11715            return false;
11716        }
11717    }
11718
11719    /**
11720     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11721     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11722     */
11723    private ProcessRecord findAppProcess(IBinder app, String reason) {
11724        if (app == null) {
11725            return null;
11726        }
11727
11728        synchronized (this) {
11729            final int NP = mProcessNames.getMap().size();
11730            for (int ip=0; ip<NP; ip++) {
11731                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11732                final int NA = apps.size();
11733                for (int ia=0; ia<NA; ia++) {
11734                    ProcessRecord p = apps.valueAt(ia);
11735                    if (p.thread != null && p.thread.asBinder() == app) {
11736                        return p;
11737                    }
11738                }
11739            }
11740
11741            Slog.w(TAG, "Can't find mystery application for " + reason
11742                    + " from pid=" + Binder.getCallingPid()
11743                    + " uid=" + Binder.getCallingUid() + ": " + app);
11744            return null;
11745        }
11746    }
11747
11748    /**
11749     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11750     * to append various headers to the dropbox log text.
11751     */
11752    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11753            StringBuilder sb) {
11754        // Watchdog thread ends up invoking this function (with
11755        // a null ProcessRecord) to add the stack file to dropbox.
11756        // Do not acquire a lock on this (am) in such cases, as it
11757        // could cause a potential deadlock, if and when watchdog
11758        // is invoked due to unavailability of lock on am and it
11759        // would prevent watchdog from killing system_server.
11760        if (process == null) {
11761            sb.append("Process: ").append(processName).append("\n");
11762            return;
11763        }
11764        // Note: ProcessRecord 'process' is guarded by the service
11765        // instance.  (notably process.pkgList, which could otherwise change
11766        // concurrently during execution of this method)
11767        synchronized (this) {
11768            sb.append("Process: ").append(processName).append("\n");
11769            int flags = process.info.flags;
11770            IPackageManager pm = AppGlobals.getPackageManager();
11771            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11772            for (int ip=0; ip<process.pkgList.size(); ip++) {
11773                String pkg = process.pkgList.keyAt(ip);
11774                sb.append("Package: ").append(pkg);
11775                try {
11776                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11777                    if (pi != null) {
11778                        sb.append(" v").append(pi.versionCode);
11779                        if (pi.versionName != null) {
11780                            sb.append(" (").append(pi.versionName).append(")");
11781                        }
11782                    }
11783                } catch (RemoteException e) {
11784                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11785                }
11786                sb.append("\n");
11787            }
11788        }
11789    }
11790
11791    private static String processClass(ProcessRecord process) {
11792        if (process == null || process.pid == MY_PID) {
11793            return "system_server";
11794        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11795            return "system_app";
11796        } else {
11797            return "data_app";
11798        }
11799    }
11800
11801    /**
11802     * Write a description of an error (crash, WTF, ANR) to the drop box.
11803     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11804     * @param process which caused the error, null means the system server
11805     * @param activity which triggered the error, null if unknown
11806     * @param parent activity related to the error, null if unknown
11807     * @param subject line related to the error, null if absent
11808     * @param report in long form describing the error, null if absent
11809     * @param logFile to include in the report, null if none
11810     * @param crashInfo giving an application stack trace, null if absent
11811     */
11812    public void addErrorToDropBox(String eventType,
11813            ProcessRecord process, String processName, ActivityRecord activity,
11814            ActivityRecord parent, String subject,
11815            final String report, final File logFile,
11816            final ApplicationErrorReport.CrashInfo crashInfo) {
11817        // NOTE -- this must never acquire the ActivityManagerService lock,
11818        // otherwise the watchdog may be prevented from resetting the system.
11819
11820        final String dropboxTag = processClass(process) + "_" + eventType;
11821        final DropBoxManager dbox = (DropBoxManager)
11822                mContext.getSystemService(Context.DROPBOX_SERVICE);
11823
11824        // Exit early if the dropbox isn't configured to accept this report type.
11825        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11826
11827        final StringBuilder sb = new StringBuilder(1024);
11828        appendDropBoxProcessHeaders(process, processName, sb);
11829        if (activity != null) {
11830            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11831        }
11832        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11833            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11834        }
11835        if (parent != null && parent != activity) {
11836            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11837        }
11838        if (subject != null) {
11839            sb.append("Subject: ").append(subject).append("\n");
11840        }
11841        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11842        if (Debug.isDebuggerConnected()) {
11843            sb.append("Debugger: Connected\n");
11844        }
11845        sb.append("\n");
11846
11847        // Do the rest in a worker thread to avoid blocking the caller on I/O
11848        // (After this point, we shouldn't access AMS internal data structures.)
11849        Thread worker = new Thread("Error dump: " + dropboxTag) {
11850            @Override
11851            public void run() {
11852                if (report != null) {
11853                    sb.append(report);
11854                }
11855                if (logFile != null) {
11856                    try {
11857                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11858                                    "\n\n[[TRUNCATED]]"));
11859                    } catch (IOException e) {
11860                        Slog.e(TAG, "Error reading " + logFile, e);
11861                    }
11862                }
11863                if (crashInfo != null && crashInfo.stackTrace != null) {
11864                    sb.append(crashInfo.stackTrace);
11865                }
11866
11867                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11868                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11869                if (lines > 0) {
11870                    sb.append("\n");
11871
11872                    // Merge several logcat streams, and take the last N lines
11873                    InputStreamReader input = null;
11874                    try {
11875                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11876                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11877                                "-b", "crash",
11878                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11879
11880                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11881                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11882                        input = new InputStreamReader(logcat.getInputStream());
11883
11884                        int num;
11885                        char[] buf = new char[8192];
11886                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11887                    } catch (IOException e) {
11888                        Slog.e(TAG, "Error running logcat", e);
11889                    } finally {
11890                        if (input != null) try { input.close(); } catch (IOException e) {}
11891                    }
11892                }
11893
11894                dbox.addText(dropboxTag, sb.toString());
11895            }
11896        };
11897
11898        if (process == null) {
11899            // If process is null, we are being called from some internal code
11900            // and may be about to die -- run this synchronously.
11901            worker.run();
11902        } else {
11903            worker.start();
11904        }
11905    }
11906
11907    /**
11908     * Bring up the "unexpected error" dialog box for a crashing app.
11909     * Deal with edge cases (intercepts from instrumented applications,
11910     * ActivityController, error intent receivers, that sort of thing).
11911     * @param r the application crashing
11912     * @param crashInfo describing the failure
11913     */
11914    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11915        long timeMillis = System.currentTimeMillis();
11916        String shortMsg = crashInfo.exceptionClassName;
11917        String longMsg = crashInfo.exceptionMessage;
11918        String stackTrace = crashInfo.stackTrace;
11919        if (shortMsg != null && longMsg != null) {
11920            longMsg = shortMsg + ": " + longMsg;
11921        } else if (shortMsg != null) {
11922            longMsg = shortMsg;
11923        }
11924
11925        AppErrorResult result = new AppErrorResult();
11926        synchronized (this) {
11927            if (mController != null) {
11928                try {
11929                    String name = r != null ? r.processName : null;
11930                    int pid = r != null ? r.pid : Binder.getCallingPid();
11931                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11932                    if (!mController.appCrashed(name, pid,
11933                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11934                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11935                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11936                            Slog.w(TAG, "Skip killing native crashed app " + name
11937                                    + "(" + pid + ") during testing");
11938                        } else {
11939                            Slog.w(TAG, "Force-killing crashed app " + name
11940                                    + " at watcher's request");
11941                            if (r != null) {
11942                                r.kill("crash", true);
11943                            } else {
11944                                // Huh.
11945                                Process.killProcess(pid);
11946                                Process.killProcessGroup(uid, pid);
11947                            }
11948                        }
11949                        return;
11950                    }
11951                } catch (RemoteException e) {
11952                    mController = null;
11953                    Watchdog.getInstance().setActivityController(null);
11954                }
11955            }
11956
11957            final long origId = Binder.clearCallingIdentity();
11958
11959            // If this process is running instrumentation, finish it.
11960            if (r != null && r.instrumentationClass != null) {
11961                Slog.w(TAG, "Error in app " + r.processName
11962                      + " running instrumentation " + r.instrumentationClass + ":");
11963                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11964                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11965                Bundle info = new Bundle();
11966                info.putString("shortMsg", shortMsg);
11967                info.putString("longMsg", longMsg);
11968                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11969                Binder.restoreCallingIdentity(origId);
11970                return;
11971            }
11972
11973            // If we can't identify the process or it's already exceeded its crash quota,
11974            // quit right away without showing a crash dialog.
11975            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11976                Binder.restoreCallingIdentity(origId);
11977                return;
11978            }
11979
11980            Message msg = Message.obtain();
11981            msg.what = SHOW_ERROR_MSG;
11982            HashMap data = new HashMap();
11983            data.put("result", result);
11984            data.put("app", r);
11985            msg.obj = data;
11986            mHandler.sendMessage(msg);
11987
11988            Binder.restoreCallingIdentity(origId);
11989        }
11990
11991        int res = result.get();
11992
11993        Intent appErrorIntent = null;
11994        synchronized (this) {
11995            if (r != null && !r.isolated) {
11996                // XXX Can't keep track of crash time for isolated processes,
11997                // since they don't have a persistent identity.
11998                mProcessCrashTimes.put(r.info.processName, r.uid,
11999                        SystemClock.uptimeMillis());
12000            }
12001            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12002                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12003            }
12004        }
12005
12006        if (appErrorIntent != null) {
12007            try {
12008                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12009            } catch (ActivityNotFoundException e) {
12010                Slog.w(TAG, "bug report receiver dissappeared", e);
12011            }
12012        }
12013    }
12014
12015    Intent createAppErrorIntentLocked(ProcessRecord r,
12016            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12017        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12018        if (report == null) {
12019            return null;
12020        }
12021        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12022        result.setComponent(r.errorReportReceiver);
12023        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12024        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12025        return result;
12026    }
12027
12028    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12029            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12030        if (r.errorReportReceiver == null) {
12031            return null;
12032        }
12033
12034        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12035            return null;
12036        }
12037
12038        ApplicationErrorReport report = new ApplicationErrorReport();
12039        report.packageName = r.info.packageName;
12040        report.installerPackageName = r.errorReportReceiver.getPackageName();
12041        report.processName = r.processName;
12042        report.time = timeMillis;
12043        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12044
12045        if (r.crashing || r.forceCrashReport) {
12046            report.type = ApplicationErrorReport.TYPE_CRASH;
12047            report.crashInfo = crashInfo;
12048        } else if (r.notResponding) {
12049            report.type = ApplicationErrorReport.TYPE_ANR;
12050            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12051
12052            report.anrInfo.activity = r.notRespondingReport.tag;
12053            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12054            report.anrInfo.info = r.notRespondingReport.longMsg;
12055        }
12056
12057        return report;
12058    }
12059
12060    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12061        enforceNotIsolatedCaller("getProcessesInErrorState");
12062        // assume our apps are happy - lazy create the list
12063        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12064
12065        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12066                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12067        int userId = UserHandle.getUserId(Binder.getCallingUid());
12068
12069        synchronized (this) {
12070
12071            // iterate across all processes
12072            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12073                ProcessRecord app = mLruProcesses.get(i);
12074                if (!allUsers && app.userId != userId) {
12075                    continue;
12076                }
12077                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12078                    // This one's in trouble, so we'll generate a report for it
12079                    // crashes are higher priority (in case there's a crash *and* an anr)
12080                    ActivityManager.ProcessErrorStateInfo report = null;
12081                    if (app.crashing) {
12082                        report = app.crashingReport;
12083                    } else if (app.notResponding) {
12084                        report = app.notRespondingReport;
12085                    }
12086
12087                    if (report != null) {
12088                        if (errList == null) {
12089                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12090                        }
12091                        errList.add(report);
12092                    } else {
12093                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12094                                " crashing = " + app.crashing +
12095                                " notResponding = " + app.notResponding);
12096                    }
12097                }
12098            }
12099        }
12100
12101        return errList;
12102    }
12103
12104    static int procStateToImportance(int procState, int memAdj,
12105            ActivityManager.RunningAppProcessInfo currApp) {
12106        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12107        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12108            currApp.lru = memAdj;
12109        } else {
12110            currApp.lru = 0;
12111        }
12112        return imp;
12113    }
12114
12115    private void fillInProcMemInfo(ProcessRecord app,
12116            ActivityManager.RunningAppProcessInfo outInfo) {
12117        outInfo.pid = app.pid;
12118        outInfo.uid = app.info.uid;
12119        if (mHeavyWeightProcess == app) {
12120            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12121        }
12122        if (app.persistent) {
12123            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12124        }
12125        if (app.activities.size() > 0) {
12126            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12127        }
12128        outInfo.lastTrimLevel = app.trimMemoryLevel;
12129        int adj = app.curAdj;
12130        int procState = app.curProcState;
12131        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12132        outInfo.importanceReasonCode = app.adjTypeCode;
12133        outInfo.processState = app.curProcState;
12134    }
12135
12136    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12137        enforceNotIsolatedCaller("getRunningAppProcesses");
12138        // Lazy instantiation of list
12139        List<ActivityManager.RunningAppProcessInfo> runList = null;
12140        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12141                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12142        int userId = UserHandle.getUserId(Binder.getCallingUid());
12143        synchronized (this) {
12144            // Iterate across all processes
12145            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12146                ProcessRecord app = mLruProcesses.get(i);
12147                if (!allUsers && app.userId != userId) {
12148                    continue;
12149                }
12150                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12151                    // Generate process state info for running application
12152                    ActivityManager.RunningAppProcessInfo currApp =
12153                        new ActivityManager.RunningAppProcessInfo(app.processName,
12154                                app.pid, app.getPackageList());
12155                    fillInProcMemInfo(app, currApp);
12156                    if (app.adjSource instanceof ProcessRecord) {
12157                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12158                        currApp.importanceReasonImportance =
12159                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12160                                        app.adjSourceProcState);
12161                    } else if (app.adjSource instanceof ActivityRecord) {
12162                        ActivityRecord r = (ActivityRecord)app.adjSource;
12163                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12164                    }
12165                    if (app.adjTarget instanceof ComponentName) {
12166                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12167                    }
12168                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12169                    //        + " lru=" + currApp.lru);
12170                    if (runList == null) {
12171                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12172                    }
12173                    runList.add(currApp);
12174                }
12175            }
12176        }
12177        return runList;
12178    }
12179
12180    public List<ApplicationInfo> getRunningExternalApplications() {
12181        enforceNotIsolatedCaller("getRunningExternalApplications");
12182        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12183        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12184        if (runningApps != null && runningApps.size() > 0) {
12185            Set<String> extList = new HashSet<String>();
12186            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12187                if (app.pkgList != null) {
12188                    for (String pkg : app.pkgList) {
12189                        extList.add(pkg);
12190                    }
12191                }
12192            }
12193            IPackageManager pm = AppGlobals.getPackageManager();
12194            for (String pkg : extList) {
12195                try {
12196                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12197                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12198                        retList.add(info);
12199                    }
12200                } catch (RemoteException e) {
12201                }
12202            }
12203        }
12204        return retList;
12205    }
12206
12207    @Override
12208    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12209        enforceNotIsolatedCaller("getMyMemoryState");
12210        synchronized (this) {
12211            ProcessRecord proc;
12212            synchronized (mPidsSelfLocked) {
12213                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12214            }
12215            fillInProcMemInfo(proc, outInfo);
12216        }
12217    }
12218
12219    @Override
12220    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12221        if (checkCallingPermission(android.Manifest.permission.DUMP)
12222                != PackageManager.PERMISSION_GRANTED) {
12223            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12224                    + Binder.getCallingPid()
12225                    + ", uid=" + Binder.getCallingUid()
12226                    + " without permission "
12227                    + android.Manifest.permission.DUMP);
12228            return;
12229        }
12230
12231        boolean dumpAll = false;
12232        boolean dumpClient = false;
12233        String dumpPackage = null;
12234
12235        int opti = 0;
12236        while (opti < args.length) {
12237            String opt = args[opti];
12238            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12239                break;
12240            }
12241            opti++;
12242            if ("-a".equals(opt)) {
12243                dumpAll = true;
12244            } else if ("-c".equals(opt)) {
12245                dumpClient = true;
12246            } else if ("-h".equals(opt)) {
12247                pw.println("Activity manager dump options:");
12248                pw.println("  [-a] [-c] [-h] [cmd] ...");
12249                pw.println("  cmd may be one of:");
12250                pw.println("    a[ctivities]: activity stack state");
12251                pw.println("    r[recents]: recent activities state");
12252                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12253                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12254                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12255                pw.println("    o[om]: out of memory management");
12256                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12257                pw.println("    provider [COMP_SPEC]: provider client-side state");
12258                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12259                pw.println("    service [COMP_SPEC]: service client-side state");
12260                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12261                pw.println("    all: dump all activities");
12262                pw.println("    top: dump the top activity");
12263                pw.println("    write: write all pending state to storage");
12264                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12265                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12266                pw.println("    a partial substring in a component name, a");
12267                pw.println("    hex object identifier.");
12268                pw.println("  -a: include all available server state.");
12269                pw.println("  -c: include client state.");
12270                return;
12271            } else {
12272                pw.println("Unknown argument: " + opt + "; use -h for help");
12273            }
12274        }
12275
12276        long origId = Binder.clearCallingIdentity();
12277        boolean more = false;
12278        // Is the caller requesting to dump a particular piece of data?
12279        if (opti < args.length) {
12280            String cmd = args[opti];
12281            opti++;
12282            if ("activities".equals(cmd) || "a".equals(cmd)) {
12283                synchronized (this) {
12284                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12285                }
12286            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12287                synchronized (this) {
12288                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12289                }
12290            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12291                String[] newArgs;
12292                String name;
12293                if (opti >= args.length) {
12294                    name = null;
12295                    newArgs = EMPTY_STRING_ARRAY;
12296                } else {
12297                    name = args[opti];
12298                    opti++;
12299                    newArgs = new String[args.length - opti];
12300                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12301                            args.length - opti);
12302                }
12303                synchronized (this) {
12304                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12305                }
12306            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12307                String[] newArgs;
12308                String name;
12309                if (opti >= args.length) {
12310                    name = null;
12311                    newArgs = EMPTY_STRING_ARRAY;
12312                } else {
12313                    name = args[opti];
12314                    opti++;
12315                    newArgs = new String[args.length - opti];
12316                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12317                            args.length - opti);
12318                }
12319                synchronized (this) {
12320                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12321                }
12322            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12323                String[] newArgs;
12324                String name;
12325                if (opti >= args.length) {
12326                    name = null;
12327                    newArgs = EMPTY_STRING_ARRAY;
12328                } else {
12329                    name = args[opti];
12330                    opti++;
12331                    newArgs = new String[args.length - opti];
12332                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12333                            args.length - opti);
12334                }
12335                synchronized (this) {
12336                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12337                }
12338            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12339                synchronized (this) {
12340                    dumpOomLocked(fd, pw, args, opti, true);
12341                }
12342            } else if ("provider".equals(cmd)) {
12343                String[] newArgs;
12344                String name;
12345                if (opti >= args.length) {
12346                    name = null;
12347                    newArgs = EMPTY_STRING_ARRAY;
12348                } else {
12349                    name = args[opti];
12350                    opti++;
12351                    newArgs = new String[args.length - opti];
12352                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12353                }
12354                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12355                    pw.println("No providers match: " + name);
12356                    pw.println("Use -h for help.");
12357                }
12358            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12359                synchronized (this) {
12360                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12361                }
12362            } else if ("service".equals(cmd)) {
12363                String[] newArgs;
12364                String name;
12365                if (opti >= args.length) {
12366                    name = null;
12367                    newArgs = EMPTY_STRING_ARRAY;
12368                } else {
12369                    name = args[opti];
12370                    opti++;
12371                    newArgs = new String[args.length - opti];
12372                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12373                            args.length - opti);
12374                }
12375                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12376                    pw.println("No services match: " + name);
12377                    pw.println("Use -h for help.");
12378                }
12379            } else if ("package".equals(cmd)) {
12380                String[] newArgs;
12381                if (opti >= args.length) {
12382                    pw.println("package: no package name specified");
12383                    pw.println("Use -h for help.");
12384                } else {
12385                    dumpPackage = args[opti];
12386                    opti++;
12387                    newArgs = new String[args.length - opti];
12388                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12389                            args.length - opti);
12390                    args = newArgs;
12391                    opti = 0;
12392                    more = true;
12393                }
12394            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12395                synchronized (this) {
12396                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12397                }
12398            } else if ("write".equals(cmd)) {
12399                mTaskPersister.flush();
12400                pw.println("All tasks persisted.");
12401                return;
12402            } else {
12403                // Dumping a single activity?
12404                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12405                    pw.println("Bad activity command, or no activities match: " + cmd);
12406                    pw.println("Use -h for help.");
12407                }
12408            }
12409            if (!more) {
12410                Binder.restoreCallingIdentity(origId);
12411                return;
12412            }
12413        }
12414
12415        // No piece of data specified, dump everything.
12416        synchronized (this) {
12417            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12418            pw.println();
12419            if (dumpAll) {
12420                pw.println("-------------------------------------------------------------------------------");
12421            }
12422            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12423            pw.println();
12424            if (dumpAll) {
12425                pw.println("-------------------------------------------------------------------------------");
12426            }
12427            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12428            pw.println();
12429            if (dumpAll) {
12430                pw.println("-------------------------------------------------------------------------------");
12431            }
12432            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12433            pw.println();
12434            if (dumpAll) {
12435                pw.println("-------------------------------------------------------------------------------");
12436            }
12437            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12438            pw.println();
12439            if (dumpAll) {
12440                pw.println("-------------------------------------------------------------------------------");
12441            }
12442            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12443            pw.println();
12444            if (dumpAll) {
12445                pw.println("-------------------------------------------------------------------------------");
12446            }
12447            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12448        }
12449        Binder.restoreCallingIdentity(origId);
12450    }
12451
12452    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12453            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12454        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12455
12456        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12457                dumpPackage);
12458        boolean needSep = printedAnything;
12459
12460        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12461                dumpPackage, needSep, "  mFocusedActivity: ");
12462        if (printed) {
12463            printedAnything = true;
12464            needSep = false;
12465        }
12466
12467        if (dumpPackage == null) {
12468            if (needSep) {
12469                pw.println();
12470            }
12471            needSep = true;
12472            printedAnything = true;
12473            mStackSupervisor.dump(pw, "  ");
12474        }
12475
12476        if (!printedAnything) {
12477            pw.println("  (nothing)");
12478        }
12479    }
12480
12481    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12482            int opti, boolean dumpAll, String dumpPackage) {
12483        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12484
12485        boolean printedAnything = false;
12486
12487        if (mRecentTasks.size() > 0) {
12488            boolean printedHeader = false;
12489
12490            final int N = mRecentTasks.size();
12491            for (int i=0; i<N; i++) {
12492                TaskRecord tr = mRecentTasks.get(i);
12493                if (dumpPackage != null) {
12494                    if (tr.realActivity == null ||
12495                            !dumpPackage.equals(tr.realActivity)) {
12496                        continue;
12497                    }
12498                }
12499                if (!printedHeader) {
12500                    pw.println("  Recent tasks:");
12501                    printedHeader = true;
12502                    printedAnything = true;
12503                }
12504                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12505                        pw.println(tr);
12506                if (dumpAll) {
12507                    mRecentTasks.get(i).dump(pw, "    ");
12508                }
12509            }
12510        }
12511
12512        if (!printedAnything) {
12513            pw.println("  (nothing)");
12514        }
12515    }
12516
12517    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12518            int opti, boolean dumpAll, String dumpPackage) {
12519        boolean needSep = false;
12520        boolean printedAnything = false;
12521        int numPers = 0;
12522
12523        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12524
12525        if (dumpAll) {
12526            final int NP = mProcessNames.getMap().size();
12527            for (int ip=0; ip<NP; ip++) {
12528                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12529                final int NA = procs.size();
12530                for (int ia=0; ia<NA; ia++) {
12531                    ProcessRecord r = procs.valueAt(ia);
12532                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12533                        continue;
12534                    }
12535                    if (!needSep) {
12536                        pw.println("  All known processes:");
12537                        needSep = true;
12538                        printedAnything = true;
12539                    }
12540                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12541                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12542                        pw.print(" "); pw.println(r);
12543                    r.dump(pw, "    ");
12544                    if (r.persistent) {
12545                        numPers++;
12546                    }
12547                }
12548            }
12549        }
12550
12551        if (mIsolatedProcesses.size() > 0) {
12552            boolean printed = false;
12553            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12554                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12555                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12556                    continue;
12557                }
12558                if (!printed) {
12559                    if (needSep) {
12560                        pw.println();
12561                    }
12562                    pw.println("  Isolated process list (sorted by uid):");
12563                    printedAnything = true;
12564                    printed = true;
12565                    needSep = true;
12566                }
12567                pw.println(String.format("%sIsolated #%2d: %s",
12568                        "    ", i, r.toString()));
12569            }
12570        }
12571
12572        if (mLruProcesses.size() > 0) {
12573            if (needSep) {
12574                pw.println();
12575            }
12576            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12577                    pw.print(" total, non-act at ");
12578                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12579                    pw.print(", non-svc at ");
12580                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12581                    pw.println("):");
12582            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12583            needSep = true;
12584            printedAnything = true;
12585        }
12586
12587        if (dumpAll || dumpPackage != null) {
12588            synchronized (mPidsSelfLocked) {
12589                boolean printed = false;
12590                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12591                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12592                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12593                        continue;
12594                    }
12595                    if (!printed) {
12596                        if (needSep) pw.println();
12597                        needSep = true;
12598                        pw.println("  PID mappings:");
12599                        printed = true;
12600                        printedAnything = true;
12601                    }
12602                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12603                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12604                }
12605            }
12606        }
12607
12608        if (mForegroundProcesses.size() > 0) {
12609            synchronized (mPidsSelfLocked) {
12610                boolean printed = false;
12611                for (int i=0; i<mForegroundProcesses.size(); i++) {
12612                    ProcessRecord r = mPidsSelfLocked.get(
12613                            mForegroundProcesses.valueAt(i).pid);
12614                    if (dumpPackage != null && (r == null
12615                            || !r.pkgList.containsKey(dumpPackage))) {
12616                        continue;
12617                    }
12618                    if (!printed) {
12619                        if (needSep) pw.println();
12620                        needSep = true;
12621                        pw.println("  Foreground Processes:");
12622                        printed = true;
12623                        printedAnything = true;
12624                    }
12625                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12626                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12627                }
12628            }
12629        }
12630
12631        if (mPersistentStartingProcesses.size() > 0) {
12632            if (needSep) pw.println();
12633            needSep = true;
12634            printedAnything = true;
12635            pw.println("  Persisent processes that are starting:");
12636            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12637                    "Starting Norm", "Restarting PERS", dumpPackage);
12638        }
12639
12640        if (mRemovedProcesses.size() > 0) {
12641            if (needSep) pw.println();
12642            needSep = true;
12643            printedAnything = true;
12644            pw.println("  Processes that are being removed:");
12645            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12646                    "Removed Norm", "Removed PERS", dumpPackage);
12647        }
12648
12649        if (mProcessesOnHold.size() > 0) {
12650            if (needSep) pw.println();
12651            needSep = true;
12652            printedAnything = true;
12653            pw.println("  Processes that are on old until the system is ready:");
12654            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12655                    "OnHold Norm", "OnHold PERS", dumpPackage);
12656        }
12657
12658        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12659
12660        if (mProcessCrashTimes.getMap().size() > 0) {
12661            boolean printed = false;
12662            long now = SystemClock.uptimeMillis();
12663            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12664            final int NP = pmap.size();
12665            for (int ip=0; ip<NP; ip++) {
12666                String pname = pmap.keyAt(ip);
12667                SparseArray<Long> uids = pmap.valueAt(ip);
12668                final int N = uids.size();
12669                for (int i=0; i<N; i++) {
12670                    int puid = uids.keyAt(i);
12671                    ProcessRecord r = mProcessNames.get(pname, puid);
12672                    if (dumpPackage != null && (r == null
12673                            || !r.pkgList.containsKey(dumpPackage))) {
12674                        continue;
12675                    }
12676                    if (!printed) {
12677                        if (needSep) pw.println();
12678                        needSep = true;
12679                        pw.println("  Time since processes crashed:");
12680                        printed = true;
12681                        printedAnything = true;
12682                    }
12683                    pw.print("    Process "); pw.print(pname);
12684                            pw.print(" uid "); pw.print(puid);
12685                            pw.print(": last crashed ");
12686                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12687                            pw.println(" ago");
12688                }
12689            }
12690        }
12691
12692        if (mBadProcesses.getMap().size() > 0) {
12693            boolean printed = false;
12694            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12695            final int NP = pmap.size();
12696            for (int ip=0; ip<NP; ip++) {
12697                String pname = pmap.keyAt(ip);
12698                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12699                final int N = uids.size();
12700                for (int i=0; i<N; i++) {
12701                    int puid = uids.keyAt(i);
12702                    ProcessRecord r = mProcessNames.get(pname, puid);
12703                    if (dumpPackage != null && (r == null
12704                            || !r.pkgList.containsKey(dumpPackage))) {
12705                        continue;
12706                    }
12707                    if (!printed) {
12708                        if (needSep) pw.println();
12709                        needSep = true;
12710                        pw.println("  Bad processes:");
12711                        printedAnything = true;
12712                    }
12713                    BadProcessInfo info = uids.valueAt(i);
12714                    pw.print("    Bad process "); pw.print(pname);
12715                            pw.print(" uid "); pw.print(puid);
12716                            pw.print(": crashed at time "); pw.println(info.time);
12717                    if (info.shortMsg != null) {
12718                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12719                    }
12720                    if (info.longMsg != null) {
12721                        pw.print("      Long msg: "); pw.println(info.longMsg);
12722                    }
12723                    if (info.stack != null) {
12724                        pw.println("      Stack:");
12725                        int lastPos = 0;
12726                        for (int pos=0; pos<info.stack.length(); pos++) {
12727                            if (info.stack.charAt(pos) == '\n') {
12728                                pw.print("        ");
12729                                pw.write(info.stack, lastPos, pos-lastPos);
12730                                pw.println();
12731                                lastPos = pos+1;
12732                            }
12733                        }
12734                        if (lastPos < info.stack.length()) {
12735                            pw.print("        ");
12736                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12737                            pw.println();
12738                        }
12739                    }
12740                }
12741            }
12742        }
12743
12744        if (dumpPackage == null) {
12745            pw.println();
12746            needSep = false;
12747            pw.println("  mStartedUsers:");
12748            for (int i=0; i<mStartedUsers.size(); i++) {
12749                UserStartedState uss = mStartedUsers.valueAt(i);
12750                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12751                        pw.print(": "); uss.dump("", pw);
12752            }
12753            pw.print("  mStartedUserArray: [");
12754            for (int i=0; i<mStartedUserArray.length; i++) {
12755                if (i > 0) pw.print(", ");
12756                pw.print(mStartedUserArray[i]);
12757            }
12758            pw.println("]");
12759            pw.print("  mUserLru: [");
12760            for (int i=0; i<mUserLru.size(); i++) {
12761                if (i > 0) pw.print(", ");
12762                pw.print(mUserLru.get(i));
12763            }
12764            pw.println("]");
12765            if (dumpAll) {
12766                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12767            }
12768            synchronized (mUserProfileGroupIdsSelfLocked) {
12769                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12770                    pw.println("  mUserProfileGroupIds:");
12771                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12772                        pw.print("    User #");
12773                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12774                        pw.print(" -> profile #");
12775                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12776                    }
12777                }
12778            }
12779        }
12780        if (mHomeProcess != null && (dumpPackage == null
12781                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12782            if (needSep) {
12783                pw.println();
12784                needSep = false;
12785            }
12786            pw.println("  mHomeProcess: " + mHomeProcess);
12787        }
12788        if (mPreviousProcess != null && (dumpPackage == null
12789                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12790            if (needSep) {
12791                pw.println();
12792                needSep = false;
12793            }
12794            pw.println("  mPreviousProcess: " + mPreviousProcess);
12795        }
12796        if (dumpAll) {
12797            StringBuilder sb = new StringBuilder(128);
12798            sb.append("  mPreviousProcessVisibleTime: ");
12799            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12800            pw.println(sb);
12801        }
12802        if (mHeavyWeightProcess != null && (dumpPackage == null
12803                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12804            if (needSep) {
12805                pw.println();
12806                needSep = false;
12807            }
12808            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12809        }
12810        if (dumpPackage == null) {
12811            pw.println("  mConfiguration: " + mConfiguration);
12812        }
12813        if (dumpAll) {
12814            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12815            if (mCompatModePackages.getPackages().size() > 0) {
12816                boolean printed = false;
12817                for (Map.Entry<String, Integer> entry
12818                        : mCompatModePackages.getPackages().entrySet()) {
12819                    String pkg = entry.getKey();
12820                    int mode = entry.getValue();
12821                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12822                        continue;
12823                    }
12824                    if (!printed) {
12825                        pw.println("  mScreenCompatPackages:");
12826                        printed = true;
12827                    }
12828                    pw.print("    "); pw.print(pkg); pw.print(": ");
12829                            pw.print(mode); pw.println();
12830                }
12831            }
12832        }
12833        if (dumpPackage == null) {
12834            if (mSleeping || mWentToSleep || mLockScreenShown) {
12835                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12836                        + " mLockScreenShown " + mLockScreenShown);
12837            }
12838            if (mShuttingDown || mRunningVoice) {
12839                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12840            }
12841        }
12842        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12843                || mOrigWaitForDebugger) {
12844            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12845                    || dumpPackage.equals(mOrigDebugApp)) {
12846                if (needSep) {
12847                    pw.println();
12848                    needSep = false;
12849                }
12850                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12851                        + " mDebugTransient=" + mDebugTransient
12852                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12853            }
12854        }
12855        if (mOpenGlTraceApp != null) {
12856            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12857                if (needSep) {
12858                    pw.println();
12859                    needSep = false;
12860                }
12861                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12862            }
12863        }
12864        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12865                || mProfileFd != null) {
12866            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12867                if (needSep) {
12868                    pw.println();
12869                    needSep = false;
12870                }
12871                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12872                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12873                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12874                        + mAutoStopProfiler);
12875                pw.println("  mProfileType=" + mProfileType);
12876            }
12877        }
12878        if (dumpPackage == null) {
12879            if (mAlwaysFinishActivities || mController != null) {
12880                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12881                        + " mController=" + mController);
12882            }
12883            if (dumpAll) {
12884                pw.println("  Total persistent processes: " + numPers);
12885                pw.println("  mProcessesReady=" + mProcessesReady
12886                        + " mSystemReady=" + mSystemReady);
12887                pw.println("  mBooting=" + mBooting
12888                        + " mBooted=" + mBooted
12889                        + " mFactoryTest=" + mFactoryTest);
12890                pw.print("  mLastPowerCheckRealtime=");
12891                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12892                        pw.println("");
12893                pw.print("  mLastPowerCheckUptime=");
12894                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12895                        pw.println("");
12896                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12897                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12898                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12899                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12900                        + " (" + mLruProcesses.size() + " total)"
12901                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12902                        + " mNumServiceProcs=" + mNumServiceProcs
12903                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12904                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12905                        + " mLastMemoryLevel" + mLastMemoryLevel
12906                        + " mLastNumProcesses" + mLastNumProcesses);
12907                long now = SystemClock.uptimeMillis();
12908                pw.print("  mLastIdleTime=");
12909                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12910                        pw.print(" mLowRamSinceLastIdle=");
12911                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12912                        pw.println();
12913            }
12914        }
12915
12916        if (!printedAnything) {
12917            pw.println("  (nothing)");
12918        }
12919    }
12920
12921    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12922            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12923        if (mProcessesToGc.size() > 0) {
12924            boolean printed = false;
12925            long now = SystemClock.uptimeMillis();
12926            for (int i=0; i<mProcessesToGc.size(); i++) {
12927                ProcessRecord proc = mProcessesToGc.get(i);
12928                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12929                    continue;
12930                }
12931                if (!printed) {
12932                    if (needSep) pw.println();
12933                    needSep = true;
12934                    pw.println("  Processes that are waiting to GC:");
12935                    printed = true;
12936                }
12937                pw.print("    Process "); pw.println(proc);
12938                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12939                        pw.print(", last gced=");
12940                        pw.print(now-proc.lastRequestedGc);
12941                        pw.print(" ms ago, last lowMem=");
12942                        pw.print(now-proc.lastLowMemory);
12943                        pw.println(" ms ago");
12944
12945            }
12946        }
12947        return needSep;
12948    }
12949
12950    void printOomLevel(PrintWriter pw, String name, int adj) {
12951        pw.print("    ");
12952        if (adj >= 0) {
12953            pw.print(' ');
12954            if (adj < 10) pw.print(' ');
12955        } else {
12956            if (adj > -10) pw.print(' ');
12957        }
12958        pw.print(adj);
12959        pw.print(": ");
12960        pw.print(name);
12961        pw.print(" (");
12962        pw.print(mProcessList.getMemLevel(adj)/1024);
12963        pw.println(" kB)");
12964    }
12965
12966    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12967            int opti, boolean dumpAll) {
12968        boolean needSep = false;
12969
12970        if (mLruProcesses.size() > 0) {
12971            if (needSep) pw.println();
12972            needSep = true;
12973            pw.println("  OOM levels:");
12974            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12975            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12976            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12977            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12978            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12979            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12980            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12981            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12982            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12983            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12984            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12985            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12986            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12987
12988            if (needSep) pw.println();
12989            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12990                    pw.print(" total, non-act at ");
12991                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12992                    pw.print(", non-svc at ");
12993                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12994                    pw.println("):");
12995            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12996            needSep = true;
12997        }
12998
12999        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13000
13001        pw.println();
13002        pw.println("  mHomeProcess: " + mHomeProcess);
13003        pw.println("  mPreviousProcess: " + mPreviousProcess);
13004        if (mHeavyWeightProcess != null) {
13005            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13006        }
13007
13008        return true;
13009    }
13010
13011    /**
13012     * There are three ways to call this:
13013     *  - no provider specified: dump all the providers
13014     *  - a flattened component name that matched an existing provider was specified as the
13015     *    first arg: dump that one provider
13016     *  - the first arg isn't the flattened component name of an existing provider:
13017     *    dump all providers whose component contains the first arg as a substring
13018     */
13019    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13020            int opti, boolean dumpAll) {
13021        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13022    }
13023
13024    static class ItemMatcher {
13025        ArrayList<ComponentName> components;
13026        ArrayList<String> strings;
13027        ArrayList<Integer> objects;
13028        boolean all;
13029
13030        ItemMatcher() {
13031            all = true;
13032        }
13033
13034        void build(String name) {
13035            ComponentName componentName = ComponentName.unflattenFromString(name);
13036            if (componentName != null) {
13037                if (components == null) {
13038                    components = new ArrayList<ComponentName>();
13039                }
13040                components.add(componentName);
13041                all = false;
13042            } else {
13043                int objectId = 0;
13044                // Not a '/' separated full component name; maybe an object ID?
13045                try {
13046                    objectId = Integer.parseInt(name, 16);
13047                    if (objects == null) {
13048                        objects = new ArrayList<Integer>();
13049                    }
13050                    objects.add(objectId);
13051                    all = false;
13052                } catch (RuntimeException e) {
13053                    // Not an integer; just do string match.
13054                    if (strings == null) {
13055                        strings = new ArrayList<String>();
13056                    }
13057                    strings.add(name);
13058                    all = false;
13059                }
13060            }
13061        }
13062
13063        int build(String[] args, int opti) {
13064            for (; opti<args.length; opti++) {
13065                String name = args[opti];
13066                if ("--".equals(name)) {
13067                    return opti+1;
13068                }
13069                build(name);
13070            }
13071            return opti;
13072        }
13073
13074        boolean match(Object object, ComponentName comp) {
13075            if (all) {
13076                return true;
13077            }
13078            if (components != null) {
13079                for (int i=0; i<components.size(); i++) {
13080                    if (components.get(i).equals(comp)) {
13081                        return true;
13082                    }
13083                }
13084            }
13085            if (objects != null) {
13086                for (int i=0; i<objects.size(); i++) {
13087                    if (System.identityHashCode(object) == objects.get(i)) {
13088                        return true;
13089                    }
13090                }
13091            }
13092            if (strings != null) {
13093                String flat = comp.flattenToString();
13094                for (int i=0; i<strings.size(); i++) {
13095                    if (flat.contains(strings.get(i))) {
13096                        return true;
13097                    }
13098                }
13099            }
13100            return false;
13101        }
13102    }
13103
13104    /**
13105     * There are three things that cmd can be:
13106     *  - a flattened component name that matches an existing activity
13107     *  - the cmd arg isn't the flattened component name of an existing activity:
13108     *    dump all activity whose component contains the cmd as a substring
13109     *  - A hex number of the ActivityRecord object instance.
13110     */
13111    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13112            int opti, boolean dumpAll) {
13113        ArrayList<ActivityRecord> activities;
13114
13115        synchronized (this) {
13116            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13117        }
13118
13119        if (activities.size() <= 0) {
13120            return false;
13121        }
13122
13123        String[] newArgs = new String[args.length - opti];
13124        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13125
13126        TaskRecord lastTask = null;
13127        boolean needSep = false;
13128        for (int i=activities.size()-1; i>=0; i--) {
13129            ActivityRecord r = activities.get(i);
13130            if (needSep) {
13131                pw.println();
13132            }
13133            needSep = true;
13134            synchronized (this) {
13135                if (lastTask != r.task) {
13136                    lastTask = r.task;
13137                    pw.print("TASK "); pw.print(lastTask.affinity);
13138                            pw.print(" id="); pw.println(lastTask.taskId);
13139                    if (dumpAll) {
13140                        lastTask.dump(pw, "  ");
13141                    }
13142                }
13143            }
13144            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13145        }
13146        return true;
13147    }
13148
13149    /**
13150     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13151     * there is a thread associated with the activity.
13152     */
13153    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13154            final ActivityRecord r, String[] args, boolean dumpAll) {
13155        String innerPrefix = prefix + "  ";
13156        synchronized (this) {
13157            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13158                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13159                    pw.print(" pid=");
13160                    if (r.app != null) pw.println(r.app.pid);
13161                    else pw.println("(not running)");
13162            if (dumpAll) {
13163                r.dump(pw, innerPrefix);
13164            }
13165        }
13166        if (r.app != null && r.app.thread != null) {
13167            // flush anything that is already in the PrintWriter since the thread is going
13168            // to write to the file descriptor directly
13169            pw.flush();
13170            try {
13171                TransferPipe tp = new TransferPipe();
13172                try {
13173                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13174                            r.appToken, innerPrefix, args);
13175                    tp.go(fd);
13176                } finally {
13177                    tp.kill();
13178                }
13179            } catch (IOException e) {
13180                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13181            } catch (RemoteException e) {
13182                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13183            }
13184        }
13185    }
13186
13187    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13188            int opti, boolean dumpAll, String dumpPackage) {
13189        boolean needSep = false;
13190        boolean onlyHistory = false;
13191        boolean printedAnything = false;
13192
13193        if ("history".equals(dumpPackage)) {
13194            if (opti < args.length && "-s".equals(args[opti])) {
13195                dumpAll = false;
13196            }
13197            onlyHistory = true;
13198            dumpPackage = null;
13199        }
13200
13201        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13202        if (!onlyHistory && dumpAll) {
13203            if (mRegisteredReceivers.size() > 0) {
13204                boolean printed = false;
13205                Iterator it = mRegisteredReceivers.values().iterator();
13206                while (it.hasNext()) {
13207                    ReceiverList r = (ReceiverList)it.next();
13208                    if (dumpPackage != null && (r.app == null ||
13209                            !dumpPackage.equals(r.app.info.packageName))) {
13210                        continue;
13211                    }
13212                    if (!printed) {
13213                        pw.println("  Registered Receivers:");
13214                        needSep = true;
13215                        printed = true;
13216                        printedAnything = true;
13217                    }
13218                    pw.print("  * "); pw.println(r);
13219                    r.dump(pw, "    ");
13220                }
13221            }
13222
13223            if (mReceiverResolver.dump(pw, needSep ?
13224                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13225                    "    ", dumpPackage, false)) {
13226                needSep = true;
13227                printedAnything = true;
13228            }
13229        }
13230
13231        for (BroadcastQueue q : mBroadcastQueues) {
13232            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13233            printedAnything |= needSep;
13234        }
13235
13236        needSep = true;
13237
13238        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13239            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13240                if (needSep) {
13241                    pw.println();
13242                }
13243                needSep = true;
13244                printedAnything = true;
13245                pw.print("  Sticky broadcasts for user ");
13246                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13247                StringBuilder sb = new StringBuilder(128);
13248                for (Map.Entry<String, ArrayList<Intent>> ent
13249                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13250                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13251                    if (dumpAll) {
13252                        pw.println(":");
13253                        ArrayList<Intent> intents = ent.getValue();
13254                        final int N = intents.size();
13255                        for (int i=0; i<N; i++) {
13256                            sb.setLength(0);
13257                            sb.append("    Intent: ");
13258                            intents.get(i).toShortString(sb, false, true, false, false);
13259                            pw.println(sb.toString());
13260                            Bundle bundle = intents.get(i).getExtras();
13261                            if (bundle != null) {
13262                                pw.print("      ");
13263                                pw.println(bundle.toString());
13264                            }
13265                        }
13266                    } else {
13267                        pw.println("");
13268                    }
13269                }
13270            }
13271        }
13272
13273        if (!onlyHistory && dumpAll) {
13274            pw.println();
13275            for (BroadcastQueue queue : mBroadcastQueues) {
13276                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13277                        + queue.mBroadcastsScheduled);
13278            }
13279            pw.println("  mHandler:");
13280            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13281            needSep = true;
13282            printedAnything = true;
13283        }
13284
13285        if (!printedAnything) {
13286            pw.println("  (nothing)");
13287        }
13288    }
13289
13290    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13291            int opti, boolean dumpAll, String dumpPackage) {
13292        boolean needSep;
13293        boolean printedAnything = false;
13294
13295        ItemMatcher matcher = new ItemMatcher();
13296        matcher.build(args, opti);
13297
13298        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13299
13300        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13301        printedAnything |= needSep;
13302
13303        if (mLaunchingProviders.size() > 0) {
13304            boolean printed = false;
13305            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13306                ContentProviderRecord r = mLaunchingProviders.get(i);
13307                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13308                    continue;
13309                }
13310                if (!printed) {
13311                    if (needSep) pw.println();
13312                    needSep = true;
13313                    pw.println("  Launching content providers:");
13314                    printed = true;
13315                    printedAnything = true;
13316                }
13317                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13318                        pw.println(r);
13319            }
13320        }
13321
13322        if (mGrantedUriPermissions.size() > 0) {
13323            boolean printed = false;
13324            int dumpUid = -2;
13325            if (dumpPackage != null) {
13326                try {
13327                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13328                } catch (NameNotFoundException e) {
13329                    dumpUid = -1;
13330                }
13331            }
13332            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13333                int uid = mGrantedUriPermissions.keyAt(i);
13334                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13335                    continue;
13336                }
13337                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13338                if (!printed) {
13339                    if (needSep) pw.println();
13340                    needSep = true;
13341                    pw.println("  Granted Uri Permissions:");
13342                    printed = true;
13343                    printedAnything = true;
13344                }
13345                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13346                for (UriPermission perm : perms.values()) {
13347                    pw.print("    "); pw.println(perm);
13348                    if (dumpAll) {
13349                        perm.dump(pw, "      ");
13350                    }
13351                }
13352            }
13353        }
13354
13355        if (!printedAnything) {
13356            pw.println("  (nothing)");
13357        }
13358    }
13359
13360    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13361            int opti, boolean dumpAll, String dumpPackage) {
13362        boolean printed = false;
13363
13364        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13365
13366        if (mIntentSenderRecords.size() > 0) {
13367            Iterator<WeakReference<PendingIntentRecord>> it
13368                    = mIntentSenderRecords.values().iterator();
13369            while (it.hasNext()) {
13370                WeakReference<PendingIntentRecord> ref = it.next();
13371                PendingIntentRecord rec = ref != null ? ref.get(): null;
13372                if (dumpPackage != null && (rec == null
13373                        || !dumpPackage.equals(rec.key.packageName))) {
13374                    continue;
13375                }
13376                printed = true;
13377                if (rec != null) {
13378                    pw.print("  * "); pw.println(rec);
13379                    if (dumpAll) {
13380                        rec.dump(pw, "    ");
13381                    }
13382                } else {
13383                    pw.print("  * "); pw.println(ref);
13384                }
13385            }
13386        }
13387
13388        if (!printed) {
13389            pw.println("  (nothing)");
13390        }
13391    }
13392
13393    private static final int dumpProcessList(PrintWriter pw,
13394            ActivityManagerService service, List list,
13395            String prefix, String normalLabel, String persistentLabel,
13396            String dumpPackage) {
13397        int numPers = 0;
13398        final int N = list.size()-1;
13399        for (int i=N; i>=0; i--) {
13400            ProcessRecord r = (ProcessRecord)list.get(i);
13401            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13402                continue;
13403            }
13404            pw.println(String.format("%s%s #%2d: %s",
13405                    prefix, (r.persistent ? persistentLabel : normalLabel),
13406                    i, r.toString()));
13407            if (r.persistent) {
13408                numPers++;
13409            }
13410        }
13411        return numPers;
13412    }
13413
13414    private static final boolean dumpProcessOomList(PrintWriter pw,
13415            ActivityManagerService service, List<ProcessRecord> origList,
13416            String prefix, String normalLabel, String persistentLabel,
13417            boolean inclDetails, String dumpPackage) {
13418
13419        ArrayList<Pair<ProcessRecord, Integer>> list
13420                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13421        for (int i=0; i<origList.size(); i++) {
13422            ProcessRecord r = origList.get(i);
13423            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13424                continue;
13425            }
13426            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13427        }
13428
13429        if (list.size() <= 0) {
13430            return false;
13431        }
13432
13433        Comparator<Pair<ProcessRecord, Integer>> comparator
13434                = new Comparator<Pair<ProcessRecord, Integer>>() {
13435            @Override
13436            public int compare(Pair<ProcessRecord, Integer> object1,
13437                    Pair<ProcessRecord, Integer> object2) {
13438                if (object1.first.setAdj != object2.first.setAdj) {
13439                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13440                }
13441                if (object1.second.intValue() != object2.second.intValue()) {
13442                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13443                }
13444                return 0;
13445            }
13446        };
13447
13448        Collections.sort(list, comparator);
13449
13450        final long curRealtime = SystemClock.elapsedRealtime();
13451        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13452        final long curUptime = SystemClock.uptimeMillis();
13453        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13454
13455        for (int i=list.size()-1; i>=0; i--) {
13456            ProcessRecord r = list.get(i).first;
13457            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13458            char schedGroup;
13459            switch (r.setSchedGroup) {
13460                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13461                    schedGroup = 'B';
13462                    break;
13463                case Process.THREAD_GROUP_DEFAULT:
13464                    schedGroup = 'F';
13465                    break;
13466                default:
13467                    schedGroup = '?';
13468                    break;
13469            }
13470            char foreground;
13471            if (r.foregroundActivities) {
13472                foreground = 'A';
13473            } else if (r.foregroundServices) {
13474                foreground = 'S';
13475            } else {
13476                foreground = ' ';
13477            }
13478            String procState = ProcessList.makeProcStateString(r.curProcState);
13479            pw.print(prefix);
13480            pw.print(r.persistent ? persistentLabel : normalLabel);
13481            pw.print(" #");
13482            int num = (origList.size()-1)-list.get(i).second;
13483            if (num < 10) pw.print(' ');
13484            pw.print(num);
13485            pw.print(": ");
13486            pw.print(oomAdj);
13487            pw.print(' ');
13488            pw.print(schedGroup);
13489            pw.print('/');
13490            pw.print(foreground);
13491            pw.print('/');
13492            pw.print(procState);
13493            pw.print(" trm:");
13494            if (r.trimMemoryLevel < 10) pw.print(' ');
13495            pw.print(r.trimMemoryLevel);
13496            pw.print(' ');
13497            pw.print(r.toShortString());
13498            pw.print(" (");
13499            pw.print(r.adjType);
13500            pw.println(')');
13501            if (r.adjSource != null || r.adjTarget != null) {
13502                pw.print(prefix);
13503                pw.print("    ");
13504                if (r.adjTarget instanceof ComponentName) {
13505                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13506                } else if (r.adjTarget != null) {
13507                    pw.print(r.adjTarget.toString());
13508                } else {
13509                    pw.print("{null}");
13510                }
13511                pw.print("<=");
13512                if (r.adjSource instanceof ProcessRecord) {
13513                    pw.print("Proc{");
13514                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13515                    pw.println("}");
13516                } else if (r.adjSource != null) {
13517                    pw.println(r.adjSource.toString());
13518                } else {
13519                    pw.println("{null}");
13520                }
13521            }
13522            if (inclDetails) {
13523                pw.print(prefix);
13524                pw.print("    ");
13525                pw.print("oom: max="); pw.print(r.maxAdj);
13526                pw.print(" curRaw="); pw.print(r.curRawAdj);
13527                pw.print(" setRaw="); pw.print(r.setRawAdj);
13528                pw.print(" cur="); pw.print(r.curAdj);
13529                pw.print(" set="); pw.println(r.setAdj);
13530                pw.print(prefix);
13531                pw.print("    ");
13532                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13533                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13534                pw.print(" lastPss="); pw.print(r.lastPss);
13535                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13536                pw.print(prefix);
13537                pw.print("    ");
13538                pw.print("cached="); pw.print(r.cached);
13539                pw.print(" empty="); pw.print(r.empty);
13540                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13541
13542                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13543                    if (r.lastWakeTime != 0) {
13544                        long wtime;
13545                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13546                        synchronized (stats) {
13547                            wtime = stats.getProcessWakeTime(r.info.uid,
13548                                    r.pid, curRealtime);
13549                        }
13550                        long timeUsed = wtime - r.lastWakeTime;
13551                        pw.print(prefix);
13552                        pw.print("    ");
13553                        pw.print("keep awake over ");
13554                        TimeUtils.formatDuration(realtimeSince, pw);
13555                        pw.print(" used ");
13556                        TimeUtils.formatDuration(timeUsed, pw);
13557                        pw.print(" (");
13558                        pw.print((timeUsed*100)/realtimeSince);
13559                        pw.println("%)");
13560                    }
13561                    if (r.lastCpuTime != 0) {
13562                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13563                        pw.print(prefix);
13564                        pw.print("    ");
13565                        pw.print("run cpu over ");
13566                        TimeUtils.formatDuration(uptimeSince, pw);
13567                        pw.print(" used ");
13568                        TimeUtils.formatDuration(timeUsed, pw);
13569                        pw.print(" (");
13570                        pw.print((timeUsed*100)/uptimeSince);
13571                        pw.println("%)");
13572                    }
13573                }
13574            }
13575        }
13576        return true;
13577    }
13578
13579    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13580        ArrayList<ProcessRecord> procs;
13581        synchronized (this) {
13582            if (args != null && args.length > start
13583                    && args[start].charAt(0) != '-') {
13584                procs = new ArrayList<ProcessRecord>();
13585                int pid = -1;
13586                try {
13587                    pid = Integer.parseInt(args[start]);
13588                } catch (NumberFormatException e) {
13589                }
13590                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13591                    ProcessRecord proc = mLruProcesses.get(i);
13592                    if (proc.pid == pid) {
13593                        procs.add(proc);
13594                    } else if (proc.processName.equals(args[start])) {
13595                        procs.add(proc);
13596                    }
13597                }
13598                if (procs.size() <= 0) {
13599                    return null;
13600                }
13601            } else {
13602                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13603            }
13604        }
13605        return procs;
13606    }
13607
13608    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13609            PrintWriter pw, String[] args) {
13610        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13611        if (procs == null) {
13612            pw.println("No process found for: " + args[0]);
13613            return;
13614        }
13615
13616        long uptime = SystemClock.uptimeMillis();
13617        long realtime = SystemClock.elapsedRealtime();
13618        pw.println("Applications Graphics Acceleration Info:");
13619        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13620
13621        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13622            ProcessRecord r = procs.get(i);
13623            if (r.thread != null) {
13624                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13625                pw.flush();
13626                try {
13627                    TransferPipe tp = new TransferPipe();
13628                    try {
13629                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13630                        tp.go(fd);
13631                    } finally {
13632                        tp.kill();
13633                    }
13634                } catch (IOException e) {
13635                    pw.println("Failure while dumping the app: " + r);
13636                    pw.flush();
13637                } catch (RemoteException e) {
13638                    pw.println("Got a RemoteException while dumping the app " + r);
13639                    pw.flush();
13640                }
13641            }
13642        }
13643    }
13644
13645    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13646        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13647        if (procs == null) {
13648            pw.println("No process found for: " + args[0]);
13649            return;
13650        }
13651
13652        pw.println("Applications Database Info:");
13653
13654        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13655            ProcessRecord r = procs.get(i);
13656            if (r.thread != null) {
13657                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13658                pw.flush();
13659                try {
13660                    TransferPipe tp = new TransferPipe();
13661                    try {
13662                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13663                        tp.go(fd);
13664                    } finally {
13665                        tp.kill();
13666                    }
13667                } catch (IOException e) {
13668                    pw.println("Failure while dumping the app: " + r);
13669                    pw.flush();
13670                } catch (RemoteException e) {
13671                    pw.println("Got a RemoteException while dumping the app " + r);
13672                    pw.flush();
13673                }
13674            }
13675        }
13676    }
13677
13678    final static class MemItem {
13679        final boolean isProc;
13680        final String label;
13681        final String shortLabel;
13682        final long pss;
13683        final int id;
13684        final boolean hasActivities;
13685        ArrayList<MemItem> subitems;
13686
13687        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13688                boolean _hasActivities) {
13689            isProc = true;
13690            label = _label;
13691            shortLabel = _shortLabel;
13692            pss = _pss;
13693            id = _id;
13694            hasActivities = _hasActivities;
13695        }
13696
13697        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13698            isProc = false;
13699            label = _label;
13700            shortLabel = _shortLabel;
13701            pss = _pss;
13702            id = _id;
13703            hasActivities = false;
13704        }
13705    }
13706
13707    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13708            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13709        if (sort && !isCompact) {
13710            Collections.sort(items, new Comparator<MemItem>() {
13711                @Override
13712                public int compare(MemItem lhs, MemItem rhs) {
13713                    if (lhs.pss < rhs.pss) {
13714                        return 1;
13715                    } else if (lhs.pss > rhs.pss) {
13716                        return -1;
13717                    }
13718                    return 0;
13719                }
13720            });
13721        }
13722
13723        for (int i=0; i<items.size(); i++) {
13724            MemItem mi = items.get(i);
13725            if (!isCompact) {
13726                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13727            } else if (mi.isProc) {
13728                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13729                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13730                pw.println(mi.hasActivities ? ",a" : ",e");
13731            } else {
13732                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13733                pw.println(mi.pss);
13734            }
13735            if (mi.subitems != null) {
13736                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13737                        true, isCompact);
13738            }
13739        }
13740    }
13741
13742    // These are in KB.
13743    static final long[] DUMP_MEM_BUCKETS = new long[] {
13744        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13745        120*1024, 160*1024, 200*1024,
13746        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13747        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13748    };
13749
13750    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13751            boolean stackLike) {
13752        int start = label.lastIndexOf('.');
13753        if (start >= 0) start++;
13754        else start = 0;
13755        int end = label.length();
13756        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13757            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13758                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13759                out.append(bucket);
13760                out.append(stackLike ? "MB." : "MB ");
13761                out.append(label, start, end);
13762                return;
13763            }
13764        }
13765        out.append(memKB/1024);
13766        out.append(stackLike ? "MB." : "MB ");
13767        out.append(label, start, end);
13768    }
13769
13770    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13771            ProcessList.NATIVE_ADJ,
13772            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13773            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13774            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13775            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13776            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13777    };
13778    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13779            "Native",
13780            "System", "Persistent", "Foreground",
13781            "Visible", "Perceptible",
13782            "Heavy Weight", "Backup",
13783            "A Services", "Home",
13784            "Previous", "B Services", "Cached"
13785    };
13786    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13787            "native",
13788            "sys", "pers", "fore",
13789            "vis", "percept",
13790            "heavy", "backup",
13791            "servicea", "home",
13792            "prev", "serviceb", "cached"
13793    };
13794
13795    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13796            long realtime, boolean isCheckinRequest, boolean isCompact) {
13797        if (isCheckinRequest || isCompact) {
13798            // short checkin version
13799            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13800        } else {
13801            pw.println("Applications Memory Usage (kB):");
13802            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13803        }
13804    }
13805
13806    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13807            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13808        boolean dumpDetails = false;
13809        boolean dumpFullDetails = false;
13810        boolean dumpDalvik = false;
13811        boolean oomOnly = false;
13812        boolean isCompact = false;
13813        boolean localOnly = false;
13814
13815        int opti = 0;
13816        while (opti < args.length) {
13817            String opt = args[opti];
13818            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13819                break;
13820            }
13821            opti++;
13822            if ("-a".equals(opt)) {
13823                dumpDetails = true;
13824                dumpFullDetails = true;
13825                dumpDalvik = true;
13826            } else if ("-d".equals(opt)) {
13827                dumpDalvik = true;
13828            } else if ("-c".equals(opt)) {
13829                isCompact = true;
13830            } else if ("--oom".equals(opt)) {
13831                oomOnly = true;
13832            } else if ("--local".equals(opt)) {
13833                localOnly = true;
13834            } else if ("-h".equals(opt)) {
13835                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13836                pw.println("  -a: include all available information for each process.");
13837                pw.println("  -d: include dalvik details when dumping process details.");
13838                pw.println("  -c: dump in a compact machine-parseable representation.");
13839                pw.println("  --oom: only show processes organized by oom adj.");
13840                pw.println("  --local: only collect details locally, don't call process.");
13841                pw.println("If [process] is specified it can be the name or ");
13842                pw.println("pid of a specific process to dump.");
13843                return;
13844            } else {
13845                pw.println("Unknown argument: " + opt + "; use -h for help");
13846            }
13847        }
13848
13849        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13850        long uptime = SystemClock.uptimeMillis();
13851        long realtime = SystemClock.elapsedRealtime();
13852        final long[] tmpLong = new long[1];
13853
13854        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13855        if (procs == null) {
13856            // No Java processes.  Maybe they want to print a native process.
13857            if (args != null && args.length > opti
13858                    && args[opti].charAt(0) != '-') {
13859                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13860                        = new ArrayList<ProcessCpuTracker.Stats>();
13861                updateCpuStatsNow();
13862                int findPid = -1;
13863                try {
13864                    findPid = Integer.parseInt(args[opti]);
13865                } catch (NumberFormatException e) {
13866                }
13867                synchronized (mProcessCpuTracker) {
13868                    final int N = mProcessCpuTracker.countStats();
13869                    for (int i=0; i<N; i++) {
13870                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13871                        if (st.pid == findPid || (st.baseName != null
13872                                && st.baseName.equals(args[opti]))) {
13873                            nativeProcs.add(st);
13874                        }
13875                    }
13876                }
13877                if (nativeProcs.size() > 0) {
13878                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13879                            isCompact);
13880                    Debug.MemoryInfo mi = null;
13881                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13882                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13883                        final int pid = r.pid;
13884                        if (!isCheckinRequest && dumpDetails) {
13885                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13886                        }
13887                        if (mi == null) {
13888                            mi = new Debug.MemoryInfo();
13889                        }
13890                        if (dumpDetails || (!brief && !oomOnly)) {
13891                            Debug.getMemoryInfo(pid, mi);
13892                        } else {
13893                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13894                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13895                        }
13896                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13897                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13898                        if (isCheckinRequest) {
13899                            pw.println();
13900                        }
13901                    }
13902                    return;
13903                }
13904            }
13905            pw.println("No process found for: " + args[opti]);
13906            return;
13907        }
13908
13909        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13910            dumpDetails = true;
13911        }
13912
13913        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13914
13915        String[] innerArgs = new String[args.length-opti];
13916        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13917
13918        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13919        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13920        long nativePss=0, dalvikPss=0, otherPss=0;
13921        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13922
13923        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13924        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13925                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13926
13927        long totalPss = 0;
13928        long cachedPss = 0;
13929
13930        Debug.MemoryInfo mi = null;
13931        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13932            final ProcessRecord r = procs.get(i);
13933            final IApplicationThread thread;
13934            final int pid;
13935            final int oomAdj;
13936            final boolean hasActivities;
13937            synchronized (this) {
13938                thread = r.thread;
13939                pid = r.pid;
13940                oomAdj = r.getSetAdjWithServices();
13941                hasActivities = r.activities.size() > 0;
13942            }
13943            if (thread != null) {
13944                if (!isCheckinRequest && dumpDetails) {
13945                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13946                }
13947                if (mi == null) {
13948                    mi = new Debug.MemoryInfo();
13949                }
13950                if (dumpDetails || (!brief && !oomOnly)) {
13951                    Debug.getMemoryInfo(pid, mi);
13952                } else {
13953                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13954                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13955                }
13956                if (dumpDetails) {
13957                    if (localOnly) {
13958                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13959                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13960                        if (isCheckinRequest) {
13961                            pw.println();
13962                        }
13963                    } else {
13964                        try {
13965                            pw.flush();
13966                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13967                                    dumpDalvik, innerArgs);
13968                        } catch (RemoteException e) {
13969                            if (!isCheckinRequest) {
13970                                pw.println("Got RemoteException!");
13971                                pw.flush();
13972                            }
13973                        }
13974                    }
13975                }
13976
13977                final long myTotalPss = mi.getTotalPss();
13978                final long myTotalUss = mi.getTotalUss();
13979
13980                synchronized (this) {
13981                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13982                        // Record this for posterity if the process has been stable.
13983                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13984                    }
13985                }
13986
13987                if (!isCheckinRequest && mi != null) {
13988                    totalPss += myTotalPss;
13989                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13990                            (hasActivities ? " / activities)" : ")"),
13991                            r.processName, myTotalPss, pid, hasActivities);
13992                    procMems.add(pssItem);
13993                    procMemsMap.put(pid, pssItem);
13994
13995                    nativePss += mi.nativePss;
13996                    dalvikPss += mi.dalvikPss;
13997                    otherPss += mi.otherPss;
13998                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13999                        long mem = mi.getOtherPss(j);
14000                        miscPss[j] += mem;
14001                        otherPss -= mem;
14002                    }
14003
14004                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14005                        cachedPss += myTotalPss;
14006                    }
14007
14008                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14009                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14010                                || oomIndex == (oomPss.length-1)) {
14011                            oomPss[oomIndex] += myTotalPss;
14012                            if (oomProcs[oomIndex] == null) {
14013                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14014                            }
14015                            oomProcs[oomIndex].add(pssItem);
14016                            break;
14017                        }
14018                    }
14019                }
14020            }
14021        }
14022
14023        long nativeProcTotalPss = 0;
14024
14025        if (!isCheckinRequest && procs.size() > 1) {
14026            // If we are showing aggregations, also look for native processes to
14027            // include so that our aggregations are more accurate.
14028            updateCpuStatsNow();
14029            synchronized (mProcessCpuTracker) {
14030                final int N = mProcessCpuTracker.countStats();
14031                for (int i=0; i<N; i++) {
14032                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14033                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14034                        if (mi == null) {
14035                            mi = new Debug.MemoryInfo();
14036                        }
14037                        if (!brief && !oomOnly) {
14038                            Debug.getMemoryInfo(st.pid, mi);
14039                        } else {
14040                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14041                            mi.nativePrivateDirty = (int)tmpLong[0];
14042                        }
14043
14044                        final long myTotalPss = mi.getTotalPss();
14045                        totalPss += myTotalPss;
14046                        nativeProcTotalPss += myTotalPss;
14047
14048                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14049                                st.name, myTotalPss, st.pid, false);
14050                        procMems.add(pssItem);
14051
14052                        nativePss += mi.nativePss;
14053                        dalvikPss += mi.dalvikPss;
14054                        otherPss += mi.otherPss;
14055                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14056                            long mem = mi.getOtherPss(j);
14057                            miscPss[j] += mem;
14058                            otherPss -= mem;
14059                        }
14060                        oomPss[0] += myTotalPss;
14061                        if (oomProcs[0] == null) {
14062                            oomProcs[0] = new ArrayList<MemItem>();
14063                        }
14064                        oomProcs[0].add(pssItem);
14065                    }
14066                }
14067            }
14068
14069            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14070
14071            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14072            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14073            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14074            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14075                String label = Debug.MemoryInfo.getOtherLabel(j);
14076                catMems.add(new MemItem(label, label, miscPss[j], j));
14077            }
14078
14079            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14080            for (int j=0; j<oomPss.length; j++) {
14081                if (oomPss[j] != 0) {
14082                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14083                            : DUMP_MEM_OOM_LABEL[j];
14084                    MemItem item = new MemItem(label, label, oomPss[j],
14085                            DUMP_MEM_OOM_ADJ[j]);
14086                    item.subitems = oomProcs[j];
14087                    oomMems.add(item);
14088                }
14089            }
14090
14091            if (!brief && !oomOnly && !isCompact) {
14092                pw.println();
14093                pw.println("Total PSS by process:");
14094                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14095                pw.println();
14096            }
14097            if (!isCompact) {
14098                pw.println("Total PSS by OOM adjustment:");
14099            }
14100            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14101            if (!brief && !oomOnly) {
14102                PrintWriter out = categoryPw != null ? categoryPw : pw;
14103                if (!isCompact) {
14104                    out.println();
14105                    out.println("Total PSS by category:");
14106                }
14107                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14108            }
14109            if (!isCompact) {
14110                pw.println();
14111            }
14112            MemInfoReader memInfo = new MemInfoReader();
14113            memInfo.readMemInfo();
14114            if (nativeProcTotalPss > 0) {
14115                synchronized (this) {
14116                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14117                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14118                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14119                            nativeProcTotalPss);
14120                }
14121            }
14122            if (!brief) {
14123                if (!isCompact) {
14124                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14125                    pw.print(" kB (status ");
14126                    switch (mLastMemoryLevel) {
14127                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14128                            pw.println("normal)");
14129                            break;
14130                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14131                            pw.println("moderate)");
14132                            break;
14133                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14134                            pw.println("low)");
14135                            break;
14136                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14137                            pw.println("critical)");
14138                            break;
14139                        default:
14140                            pw.print(mLastMemoryLevel);
14141                            pw.println(")");
14142                            break;
14143                    }
14144                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14145                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14146                            pw.print(cachedPss); pw.print(" cached pss + ");
14147                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14148                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14149                } else {
14150                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14151                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14152                            + memInfo.getFreeSizeKb()); pw.print(",");
14153                    pw.println(totalPss - cachedPss);
14154                }
14155            }
14156            if (!isCompact) {
14157                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14158                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14159                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14160                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14161                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14162                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14163                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14164                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14165                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14166                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14167                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14168            }
14169            if (!brief) {
14170                if (memInfo.getZramTotalSizeKb() != 0) {
14171                    if (!isCompact) {
14172                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14173                                pw.print(" kB physical used for ");
14174                                pw.print(memInfo.getSwapTotalSizeKb()
14175                                        - memInfo.getSwapFreeSizeKb());
14176                                pw.print(" kB in swap (");
14177                                pw.print(memInfo.getSwapTotalSizeKb());
14178                                pw.println(" kB total swap)");
14179                    } else {
14180                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14181                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14182                                pw.println(memInfo.getSwapFreeSizeKb());
14183                    }
14184                }
14185                final int[] SINGLE_LONG_FORMAT = new int[] {
14186                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14187                };
14188                long[] longOut = new long[1];
14189                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14190                        SINGLE_LONG_FORMAT, null, longOut, null);
14191                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14192                longOut[0] = 0;
14193                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14194                        SINGLE_LONG_FORMAT, null, longOut, null);
14195                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14196                longOut[0] = 0;
14197                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14198                        SINGLE_LONG_FORMAT, null, longOut, null);
14199                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14200                longOut[0] = 0;
14201                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14202                        SINGLE_LONG_FORMAT, null, longOut, null);
14203                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14204                if (!isCompact) {
14205                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14206                        pw.print("      KSM: "); pw.print(sharing);
14207                                pw.print(" kB saved from shared ");
14208                                pw.print(shared); pw.println(" kB");
14209                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14210                                pw.print(voltile); pw.println(" kB volatile");
14211                    }
14212                    pw.print("   Tuning: ");
14213                    pw.print(ActivityManager.staticGetMemoryClass());
14214                    pw.print(" (large ");
14215                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14216                    pw.print("), oom ");
14217                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14218                    pw.print(" kB");
14219                    pw.print(", restore limit ");
14220                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14221                    pw.print(" kB");
14222                    if (ActivityManager.isLowRamDeviceStatic()) {
14223                        pw.print(" (low-ram)");
14224                    }
14225                    if (ActivityManager.isHighEndGfx()) {
14226                        pw.print(" (high-end-gfx)");
14227                    }
14228                    pw.println();
14229                } else {
14230                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14231                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14232                    pw.println(voltile);
14233                    pw.print("tuning,");
14234                    pw.print(ActivityManager.staticGetMemoryClass());
14235                    pw.print(',');
14236                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14237                    pw.print(',');
14238                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14239                    if (ActivityManager.isLowRamDeviceStatic()) {
14240                        pw.print(",low-ram");
14241                    }
14242                    if (ActivityManager.isHighEndGfx()) {
14243                        pw.print(",high-end-gfx");
14244                    }
14245                    pw.println();
14246                }
14247            }
14248        }
14249    }
14250
14251    /**
14252     * Searches array of arguments for the specified string
14253     * @param args array of argument strings
14254     * @param value value to search for
14255     * @return true if the value is contained in the array
14256     */
14257    private static boolean scanArgs(String[] args, String value) {
14258        if (args != null) {
14259            for (String arg : args) {
14260                if (value.equals(arg)) {
14261                    return true;
14262                }
14263            }
14264        }
14265        return false;
14266    }
14267
14268    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14269            ContentProviderRecord cpr, boolean always) {
14270        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14271
14272        if (!inLaunching || always) {
14273            synchronized (cpr) {
14274                cpr.launchingApp = null;
14275                cpr.notifyAll();
14276            }
14277            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14278            String names[] = cpr.info.authority.split(";");
14279            for (int j = 0; j < names.length; j++) {
14280                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14281            }
14282        }
14283
14284        for (int i=0; i<cpr.connections.size(); i++) {
14285            ContentProviderConnection conn = cpr.connections.get(i);
14286            if (conn.waiting) {
14287                // If this connection is waiting for the provider, then we don't
14288                // need to mess with its process unless we are always removing
14289                // or for some reason the provider is not currently launching.
14290                if (inLaunching && !always) {
14291                    continue;
14292                }
14293            }
14294            ProcessRecord capp = conn.client;
14295            conn.dead = true;
14296            if (conn.stableCount > 0) {
14297                if (!capp.persistent && capp.thread != null
14298                        && capp.pid != 0
14299                        && capp.pid != MY_PID) {
14300                    capp.kill("depends on provider "
14301                            + cpr.name.flattenToShortString()
14302                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14303                }
14304            } else if (capp.thread != null && conn.provider.provider != null) {
14305                try {
14306                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14307                } catch (RemoteException e) {
14308                }
14309                // In the protocol here, we don't expect the client to correctly
14310                // clean up this connection, we'll just remove it.
14311                cpr.connections.remove(i);
14312                conn.client.conProviders.remove(conn);
14313            }
14314        }
14315
14316        if (inLaunching && always) {
14317            mLaunchingProviders.remove(cpr);
14318        }
14319        return inLaunching;
14320    }
14321
14322    /**
14323     * Main code for cleaning up a process when it has gone away.  This is
14324     * called both as a result of the process dying, or directly when stopping
14325     * a process when running in single process mode.
14326     *
14327     * @return Returns true if the given process has been restarted, so the
14328     * app that was passed in must remain on the process lists.
14329     */
14330    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14331            boolean restarting, boolean allowRestart, int index) {
14332        if (index >= 0) {
14333            removeLruProcessLocked(app);
14334            ProcessList.remove(app.pid);
14335        }
14336
14337        mProcessesToGc.remove(app);
14338        mPendingPssProcesses.remove(app);
14339
14340        // Dismiss any open dialogs.
14341        if (app.crashDialog != null && !app.forceCrashReport) {
14342            app.crashDialog.dismiss();
14343            app.crashDialog = null;
14344        }
14345        if (app.anrDialog != null) {
14346            app.anrDialog.dismiss();
14347            app.anrDialog = null;
14348        }
14349        if (app.waitDialog != null) {
14350            app.waitDialog.dismiss();
14351            app.waitDialog = null;
14352        }
14353
14354        app.crashing = false;
14355        app.notResponding = false;
14356
14357        app.resetPackageList(mProcessStats);
14358        app.unlinkDeathRecipient();
14359        app.makeInactive(mProcessStats);
14360        app.waitingToKill = null;
14361        app.forcingToForeground = null;
14362        updateProcessForegroundLocked(app, false, false);
14363        app.foregroundActivities = false;
14364        app.hasShownUi = false;
14365        app.treatLikeActivity = false;
14366        app.hasAboveClient = false;
14367        app.hasClientActivities = false;
14368
14369        mServices.killServicesLocked(app, allowRestart);
14370
14371        boolean restart = false;
14372
14373        // Remove published content providers.
14374        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14375            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14376            final boolean always = app.bad || !allowRestart;
14377            if (removeDyingProviderLocked(app, cpr, always) || always) {
14378                // We left the provider in the launching list, need to
14379                // restart it.
14380                restart = true;
14381            }
14382
14383            cpr.provider = null;
14384            cpr.proc = null;
14385        }
14386        app.pubProviders.clear();
14387
14388        // Take care of any launching providers waiting for this process.
14389        if (checkAppInLaunchingProvidersLocked(app, false)) {
14390            restart = true;
14391        }
14392
14393        // Unregister from connected content providers.
14394        if (!app.conProviders.isEmpty()) {
14395            for (int i=0; i<app.conProviders.size(); i++) {
14396                ContentProviderConnection conn = app.conProviders.get(i);
14397                conn.provider.connections.remove(conn);
14398            }
14399            app.conProviders.clear();
14400        }
14401
14402        // At this point there may be remaining entries in mLaunchingProviders
14403        // where we were the only one waiting, so they are no longer of use.
14404        // Look for these and clean up if found.
14405        // XXX Commented out for now.  Trying to figure out a way to reproduce
14406        // the actual situation to identify what is actually going on.
14407        if (false) {
14408            for (int i=0; i<mLaunchingProviders.size(); i++) {
14409                ContentProviderRecord cpr = (ContentProviderRecord)
14410                        mLaunchingProviders.get(i);
14411                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14412                    synchronized (cpr) {
14413                        cpr.launchingApp = null;
14414                        cpr.notifyAll();
14415                    }
14416                }
14417            }
14418        }
14419
14420        skipCurrentReceiverLocked(app);
14421
14422        // Unregister any receivers.
14423        for (int i=app.receivers.size()-1; i>=0; i--) {
14424            removeReceiverLocked(app.receivers.valueAt(i));
14425        }
14426        app.receivers.clear();
14427
14428        // If the app is undergoing backup, tell the backup manager about it
14429        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14430            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14431                    + mBackupTarget.appInfo + " died during backup");
14432            try {
14433                IBackupManager bm = IBackupManager.Stub.asInterface(
14434                        ServiceManager.getService(Context.BACKUP_SERVICE));
14435                bm.agentDisconnected(app.info.packageName);
14436            } catch (RemoteException e) {
14437                // can't happen; backup manager is local
14438            }
14439        }
14440
14441        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14442            ProcessChangeItem item = mPendingProcessChanges.get(i);
14443            if (item.pid == app.pid) {
14444                mPendingProcessChanges.remove(i);
14445                mAvailProcessChanges.add(item);
14446            }
14447        }
14448        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14449
14450        // If the caller is restarting this app, then leave it in its
14451        // current lists and let the caller take care of it.
14452        if (restarting) {
14453            return false;
14454        }
14455
14456        if (!app.persistent || app.isolated) {
14457            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14458                    "Removing non-persistent process during cleanup: " + app);
14459            mProcessNames.remove(app.processName, app.uid);
14460            mIsolatedProcesses.remove(app.uid);
14461            if (mHeavyWeightProcess == app) {
14462                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14463                        mHeavyWeightProcess.userId, 0));
14464                mHeavyWeightProcess = null;
14465            }
14466        } else if (!app.removed) {
14467            // This app is persistent, so we need to keep its record around.
14468            // If it is not already on the pending app list, add it there
14469            // and start a new process for it.
14470            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14471                mPersistentStartingProcesses.add(app);
14472                restart = true;
14473            }
14474        }
14475        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14476                "Clean-up removing on hold: " + app);
14477        mProcessesOnHold.remove(app);
14478
14479        if (app == mHomeProcess) {
14480            mHomeProcess = null;
14481        }
14482        if (app == mPreviousProcess) {
14483            mPreviousProcess = null;
14484        }
14485
14486        if (restart && !app.isolated) {
14487            // We have components that still need to be running in the
14488            // process, so re-launch it.
14489            if (index < 0) {
14490                ProcessList.remove(app.pid);
14491            }
14492            mProcessNames.put(app.processName, app.uid, app);
14493            startProcessLocked(app, "restart", app.processName);
14494            return true;
14495        } else if (app.pid > 0 && app.pid != MY_PID) {
14496            // Goodbye!
14497            boolean removed;
14498            synchronized (mPidsSelfLocked) {
14499                mPidsSelfLocked.remove(app.pid);
14500                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14501            }
14502            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14503            if (app.isolated) {
14504                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14505            }
14506            app.setPid(0);
14507        }
14508        return false;
14509    }
14510
14511    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14512        // Look through the content providers we are waiting to have launched,
14513        // and if any run in this process then either schedule a restart of
14514        // the process or kill the client waiting for it if this process has
14515        // gone bad.
14516        int NL = mLaunchingProviders.size();
14517        boolean restart = false;
14518        for (int i=0; i<NL; i++) {
14519            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14520            if (cpr.launchingApp == app) {
14521                if (!alwaysBad && !app.bad) {
14522                    restart = true;
14523                } else {
14524                    removeDyingProviderLocked(app, cpr, true);
14525                    // cpr should have been removed from mLaunchingProviders
14526                    NL = mLaunchingProviders.size();
14527                    i--;
14528                }
14529            }
14530        }
14531        return restart;
14532    }
14533
14534    // =========================================================
14535    // SERVICES
14536    // =========================================================
14537
14538    @Override
14539    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14540            int flags) {
14541        enforceNotIsolatedCaller("getServices");
14542        synchronized (this) {
14543            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14544        }
14545    }
14546
14547    @Override
14548    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14549        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14550        synchronized (this) {
14551            return mServices.getRunningServiceControlPanelLocked(name);
14552        }
14553    }
14554
14555    @Override
14556    public ComponentName startService(IApplicationThread caller, Intent service,
14557            String resolvedType, int userId) {
14558        enforceNotIsolatedCaller("startService");
14559        // Refuse possible leaked file descriptors
14560        if (service != null && service.hasFileDescriptors() == true) {
14561            throw new IllegalArgumentException("File descriptors passed in Intent");
14562        }
14563
14564        if (DEBUG_SERVICE)
14565            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14566        synchronized(this) {
14567            final int callingPid = Binder.getCallingPid();
14568            final int callingUid = Binder.getCallingUid();
14569            final long origId = Binder.clearCallingIdentity();
14570            ComponentName res = mServices.startServiceLocked(caller, service,
14571                    resolvedType, callingPid, callingUid, userId);
14572            Binder.restoreCallingIdentity(origId);
14573            return res;
14574        }
14575    }
14576
14577    ComponentName startServiceInPackage(int uid,
14578            Intent service, String resolvedType, int userId) {
14579        synchronized(this) {
14580            if (DEBUG_SERVICE)
14581                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14582            final long origId = Binder.clearCallingIdentity();
14583            ComponentName res = mServices.startServiceLocked(null, service,
14584                    resolvedType, -1, uid, userId);
14585            Binder.restoreCallingIdentity(origId);
14586            return res;
14587        }
14588    }
14589
14590    @Override
14591    public int stopService(IApplicationThread caller, Intent service,
14592            String resolvedType, int userId) {
14593        enforceNotIsolatedCaller("stopService");
14594        // Refuse possible leaked file descriptors
14595        if (service != null && service.hasFileDescriptors() == true) {
14596            throw new IllegalArgumentException("File descriptors passed in Intent");
14597        }
14598
14599        synchronized(this) {
14600            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14601        }
14602    }
14603
14604    @Override
14605    public IBinder peekService(Intent service, String resolvedType) {
14606        enforceNotIsolatedCaller("peekService");
14607        // Refuse possible leaked file descriptors
14608        if (service != null && service.hasFileDescriptors() == true) {
14609            throw new IllegalArgumentException("File descriptors passed in Intent");
14610        }
14611        synchronized(this) {
14612            return mServices.peekServiceLocked(service, resolvedType);
14613        }
14614    }
14615
14616    @Override
14617    public boolean stopServiceToken(ComponentName className, IBinder token,
14618            int startId) {
14619        synchronized(this) {
14620            return mServices.stopServiceTokenLocked(className, token, startId);
14621        }
14622    }
14623
14624    @Override
14625    public void setServiceForeground(ComponentName className, IBinder token,
14626            int id, Notification notification, boolean removeNotification) {
14627        synchronized(this) {
14628            mServices.setServiceForegroundLocked(className, token, id, notification,
14629                    removeNotification);
14630        }
14631    }
14632
14633    @Override
14634    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14635            boolean requireFull, String name, String callerPackage) {
14636        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14637                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14638    }
14639
14640    int unsafeConvertIncomingUser(int userId) {
14641        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14642                ? mCurrentUserId : userId;
14643    }
14644
14645    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14646            int allowMode, String name, String callerPackage) {
14647        final int callingUserId = UserHandle.getUserId(callingUid);
14648        if (callingUserId == userId) {
14649            return userId;
14650        }
14651
14652        // Note that we may be accessing mCurrentUserId outside of a lock...
14653        // shouldn't be a big deal, if this is being called outside
14654        // of a locked context there is intrinsically a race with
14655        // the value the caller will receive and someone else changing it.
14656        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14657        // we will switch to the calling user if access to the current user fails.
14658        int targetUserId = unsafeConvertIncomingUser(userId);
14659
14660        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14661            final boolean allow;
14662            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14663                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14664                // If the caller has this permission, they always pass go.  And collect $200.
14665                allow = true;
14666            } else if (allowMode == ALLOW_FULL_ONLY) {
14667                // We require full access, sucks to be you.
14668                allow = false;
14669            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14670                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14671                // If the caller does not have either permission, they are always doomed.
14672                allow = false;
14673            } else if (allowMode == ALLOW_NON_FULL) {
14674                // We are blanket allowing non-full access, you lucky caller!
14675                allow = true;
14676            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14677                // We may or may not allow this depending on whether the two users are
14678                // in the same profile.
14679                synchronized (mUserProfileGroupIdsSelfLocked) {
14680                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14681                            UserInfo.NO_PROFILE_GROUP_ID);
14682                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14683                            UserInfo.NO_PROFILE_GROUP_ID);
14684                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14685                            && callingProfile == targetProfile;
14686                }
14687            } else {
14688                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14689            }
14690            if (!allow) {
14691                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14692                    // In this case, they would like to just execute as their
14693                    // owner user instead of failing.
14694                    targetUserId = callingUserId;
14695                } else {
14696                    StringBuilder builder = new StringBuilder(128);
14697                    builder.append("Permission Denial: ");
14698                    builder.append(name);
14699                    if (callerPackage != null) {
14700                        builder.append(" from ");
14701                        builder.append(callerPackage);
14702                    }
14703                    builder.append(" asks to run as user ");
14704                    builder.append(userId);
14705                    builder.append(" but is calling from user ");
14706                    builder.append(UserHandle.getUserId(callingUid));
14707                    builder.append("; this requires ");
14708                    builder.append(INTERACT_ACROSS_USERS_FULL);
14709                    if (allowMode != ALLOW_FULL_ONLY) {
14710                        builder.append(" or ");
14711                        builder.append(INTERACT_ACROSS_USERS);
14712                    }
14713                    String msg = builder.toString();
14714                    Slog.w(TAG, msg);
14715                    throw new SecurityException(msg);
14716                }
14717            }
14718        }
14719        if (!allowAll && targetUserId < 0) {
14720            throw new IllegalArgumentException(
14721                    "Call does not support special user #" + targetUserId);
14722        }
14723        // Check shell permission
14724        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14725            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14726                    targetUserId)) {
14727                throw new SecurityException("Shell does not have permission to access user "
14728                        + targetUserId + "\n " + Debug.getCallers(3));
14729            }
14730        }
14731        return targetUserId;
14732    }
14733
14734    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14735            String className, int flags) {
14736        boolean result = false;
14737        // For apps that don't have pre-defined UIDs, check for permission
14738        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14739            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14740                if (ActivityManager.checkUidPermission(
14741                        INTERACT_ACROSS_USERS,
14742                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14743                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14744                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14745                            + " requests FLAG_SINGLE_USER, but app does not hold "
14746                            + INTERACT_ACROSS_USERS;
14747                    Slog.w(TAG, msg);
14748                    throw new SecurityException(msg);
14749                }
14750                // Permission passed
14751                result = true;
14752            }
14753        } else if ("system".equals(componentProcessName)) {
14754            result = true;
14755        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14756            // Phone app and persistent apps are allowed to export singleuser providers.
14757            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14758                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14759        }
14760        if (DEBUG_MU) {
14761            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14762                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14763        }
14764        return result;
14765    }
14766
14767    /**
14768     * Checks to see if the caller is in the same app as the singleton
14769     * component, or the component is in a special app. It allows special apps
14770     * to export singleton components but prevents exporting singleton
14771     * components for regular apps.
14772     */
14773    boolean isValidSingletonCall(int callingUid, int componentUid) {
14774        int componentAppId = UserHandle.getAppId(componentUid);
14775        return UserHandle.isSameApp(callingUid, componentUid)
14776                || componentAppId == Process.SYSTEM_UID
14777                || componentAppId == Process.PHONE_UID
14778                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14779                        == PackageManager.PERMISSION_GRANTED;
14780    }
14781
14782    public int bindService(IApplicationThread caller, IBinder token,
14783            Intent service, String resolvedType,
14784            IServiceConnection connection, int flags, int userId) {
14785        enforceNotIsolatedCaller("bindService");
14786
14787        // Refuse possible leaked file descriptors
14788        if (service != null && service.hasFileDescriptors() == true) {
14789            throw new IllegalArgumentException("File descriptors passed in Intent");
14790        }
14791
14792        synchronized(this) {
14793            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14794                    connection, flags, userId);
14795        }
14796    }
14797
14798    public boolean unbindService(IServiceConnection connection) {
14799        synchronized (this) {
14800            return mServices.unbindServiceLocked(connection);
14801        }
14802    }
14803
14804    public void publishService(IBinder token, Intent intent, IBinder service) {
14805        // Refuse possible leaked file descriptors
14806        if (intent != null && intent.hasFileDescriptors() == true) {
14807            throw new IllegalArgumentException("File descriptors passed in Intent");
14808        }
14809
14810        synchronized(this) {
14811            if (!(token instanceof ServiceRecord)) {
14812                throw new IllegalArgumentException("Invalid service token");
14813            }
14814            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14815        }
14816    }
14817
14818    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14819        // Refuse possible leaked file descriptors
14820        if (intent != null && intent.hasFileDescriptors() == true) {
14821            throw new IllegalArgumentException("File descriptors passed in Intent");
14822        }
14823
14824        synchronized(this) {
14825            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14826        }
14827    }
14828
14829    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14830        synchronized(this) {
14831            if (!(token instanceof ServiceRecord)) {
14832                throw new IllegalArgumentException("Invalid service token");
14833            }
14834            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14835        }
14836    }
14837
14838    // =========================================================
14839    // BACKUP AND RESTORE
14840    // =========================================================
14841
14842    // Cause the target app to be launched if necessary and its backup agent
14843    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14844    // activity manager to announce its creation.
14845    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14846        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14847        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14848
14849        synchronized(this) {
14850            // !!! TODO: currently no check here that we're already bound
14851            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14852            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14853            synchronized (stats) {
14854                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14855            }
14856
14857            // Backup agent is now in use, its package can't be stopped.
14858            try {
14859                AppGlobals.getPackageManager().setPackageStoppedState(
14860                        app.packageName, false, UserHandle.getUserId(app.uid));
14861            } catch (RemoteException e) {
14862            } catch (IllegalArgumentException e) {
14863                Slog.w(TAG, "Failed trying to unstop package "
14864                        + app.packageName + ": " + e);
14865            }
14866
14867            BackupRecord r = new BackupRecord(ss, app, backupMode);
14868            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14869                    ? new ComponentName(app.packageName, app.backupAgentName)
14870                    : new ComponentName("android", "FullBackupAgent");
14871            // startProcessLocked() returns existing proc's record if it's already running
14872            ProcessRecord proc = startProcessLocked(app.processName, app,
14873                    false, 0, "backup", hostingName, false, false, false);
14874            if (proc == null) {
14875                Slog.e(TAG, "Unable to start backup agent process " + r);
14876                return false;
14877            }
14878
14879            r.app = proc;
14880            mBackupTarget = r;
14881            mBackupAppName = app.packageName;
14882
14883            // Try not to kill the process during backup
14884            updateOomAdjLocked(proc);
14885
14886            // If the process is already attached, schedule the creation of the backup agent now.
14887            // If it is not yet live, this will be done when it attaches to the framework.
14888            if (proc.thread != null) {
14889                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14890                try {
14891                    proc.thread.scheduleCreateBackupAgent(app,
14892                            compatibilityInfoForPackageLocked(app), backupMode);
14893                } catch (RemoteException e) {
14894                    // Will time out on the backup manager side
14895                }
14896            } else {
14897                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14898            }
14899            // Invariants: at this point, the target app process exists and the application
14900            // is either already running or in the process of coming up.  mBackupTarget and
14901            // mBackupAppName describe the app, so that when it binds back to the AM we
14902            // know that it's scheduled for a backup-agent operation.
14903        }
14904
14905        return true;
14906    }
14907
14908    @Override
14909    public void clearPendingBackup() {
14910        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14911        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14912
14913        synchronized (this) {
14914            mBackupTarget = null;
14915            mBackupAppName = null;
14916        }
14917    }
14918
14919    // A backup agent has just come up
14920    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14921        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14922                + " = " + agent);
14923
14924        synchronized(this) {
14925            if (!agentPackageName.equals(mBackupAppName)) {
14926                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14927                return;
14928            }
14929        }
14930
14931        long oldIdent = Binder.clearCallingIdentity();
14932        try {
14933            IBackupManager bm = IBackupManager.Stub.asInterface(
14934                    ServiceManager.getService(Context.BACKUP_SERVICE));
14935            bm.agentConnected(agentPackageName, agent);
14936        } catch (RemoteException e) {
14937            // can't happen; the backup manager service is local
14938        } catch (Exception e) {
14939            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14940            e.printStackTrace();
14941        } finally {
14942            Binder.restoreCallingIdentity(oldIdent);
14943        }
14944    }
14945
14946    // done with this agent
14947    public void unbindBackupAgent(ApplicationInfo appInfo) {
14948        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14949        if (appInfo == null) {
14950            Slog.w(TAG, "unbind backup agent for null app");
14951            return;
14952        }
14953
14954        synchronized(this) {
14955            try {
14956                if (mBackupAppName == null) {
14957                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14958                    return;
14959                }
14960
14961                if (!mBackupAppName.equals(appInfo.packageName)) {
14962                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14963                    return;
14964                }
14965
14966                // Not backing this app up any more; reset its OOM adjustment
14967                final ProcessRecord proc = mBackupTarget.app;
14968                updateOomAdjLocked(proc);
14969
14970                // If the app crashed during backup, 'thread' will be null here
14971                if (proc.thread != null) {
14972                    try {
14973                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14974                                compatibilityInfoForPackageLocked(appInfo));
14975                    } catch (Exception e) {
14976                        Slog.e(TAG, "Exception when unbinding backup agent:");
14977                        e.printStackTrace();
14978                    }
14979                }
14980            } finally {
14981                mBackupTarget = null;
14982                mBackupAppName = null;
14983            }
14984        }
14985    }
14986    // =========================================================
14987    // BROADCASTS
14988    // =========================================================
14989
14990    private final List getStickiesLocked(String action, IntentFilter filter,
14991            List cur, int userId) {
14992        final ContentResolver resolver = mContext.getContentResolver();
14993        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14994        if (stickies == null) {
14995            return cur;
14996        }
14997        final ArrayList<Intent> list = stickies.get(action);
14998        if (list == null) {
14999            return cur;
15000        }
15001        int N = list.size();
15002        for (int i=0; i<N; i++) {
15003            Intent intent = list.get(i);
15004            if (filter.match(resolver, intent, true, TAG) >= 0) {
15005                if (cur == null) {
15006                    cur = new ArrayList<Intent>();
15007                }
15008                cur.add(intent);
15009            }
15010        }
15011        return cur;
15012    }
15013
15014    boolean isPendingBroadcastProcessLocked(int pid) {
15015        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15016                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15017    }
15018
15019    void skipPendingBroadcastLocked(int pid) {
15020            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15021            for (BroadcastQueue queue : mBroadcastQueues) {
15022                queue.skipPendingBroadcastLocked(pid);
15023            }
15024    }
15025
15026    // The app just attached; send any pending broadcasts that it should receive
15027    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15028        boolean didSomething = false;
15029        for (BroadcastQueue queue : mBroadcastQueues) {
15030            didSomething |= queue.sendPendingBroadcastsLocked(app);
15031        }
15032        return didSomething;
15033    }
15034
15035    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15036            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15037        enforceNotIsolatedCaller("registerReceiver");
15038        int callingUid;
15039        int callingPid;
15040        synchronized(this) {
15041            ProcessRecord callerApp = null;
15042            if (caller != null) {
15043                callerApp = getRecordForAppLocked(caller);
15044                if (callerApp == null) {
15045                    throw new SecurityException(
15046                            "Unable to find app for caller " + caller
15047                            + " (pid=" + Binder.getCallingPid()
15048                            + ") when registering receiver " + receiver);
15049                }
15050                if (callerApp.info.uid != Process.SYSTEM_UID &&
15051                        !callerApp.pkgList.containsKey(callerPackage) &&
15052                        !"android".equals(callerPackage)) {
15053                    throw new SecurityException("Given caller package " + callerPackage
15054                            + " is not running in process " + callerApp);
15055                }
15056                callingUid = callerApp.info.uid;
15057                callingPid = callerApp.pid;
15058            } else {
15059                callerPackage = null;
15060                callingUid = Binder.getCallingUid();
15061                callingPid = Binder.getCallingPid();
15062            }
15063
15064            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15065                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15066
15067            List allSticky = null;
15068
15069            // Look for any matching sticky broadcasts...
15070            Iterator actions = filter.actionsIterator();
15071            if (actions != null) {
15072                while (actions.hasNext()) {
15073                    String action = (String)actions.next();
15074                    allSticky = getStickiesLocked(action, filter, allSticky,
15075                            UserHandle.USER_ALL);
15076                    allSticky = getStickiesLocked(action, filter, allSticky,
15077                            UserHandle.getUserId(callingUid));
15078                }
15079            } else {
15080                allSticky = getStickiesLocked(null, filter, allSticky,
15081                        UserHandle.USER_ALL);
15082                allSticky = getStickiesLocked(null, filter, allSticky,
15083                        UserHandle.getUserId(callingUid));
15084            }
15085
15086            // The first sticky in the list is returned directly back to
15087            // the client.
15088            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15089
15090            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15091                    + ": " + sticky);
15092
15093            if (receiver == null) {
15094                return sticky;
15095            }
15096
15097            ReceiverList rl
15098                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15099            if (rl == null) {
15100                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15101                        userId, receiver);
15102                if (rl.app != null) {
15103                    rl.app.receivers.add(rl);
15104                } else {
15105                    try {
15106                        receiver.asBinder().linkToDeath(rl, 0);
15107                    } catch (RemoteException e) {
15108                        return sticky;
15109                    }
15110                    rl.linkedToDeath = true;
15111                }
15112                mRegisteredReceivers.put(receiver.asBinder(), rl);
15113            } else if (rl.uid != callingUid) {
15114                throw new IllegalArgumentException(
15115                        "Receiver requested to register for uid " + callingUid
15116                        + " was previously registered for uid " + rl.uid);
15117            } else if (rl.pid != callingPid) {
15118                throw new IllegalArgumentException(
15119                        "Receiver requested to register for pid " + callingPid
15120                        + " was previously registered for pid " + rl.pid);
15121            } else if (rl.userId != userId) {
15122                throw new IllegalArgumentException(
15123                        "Receiver requested to register for user " + userId
15124                        + " was previously registered for user " + rl.userId);
15125            }
15126            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15127                    permission, callingUid, userId);
15128            rl.add(bf);
15129            if (!bf.debugCheck()) {
15130                Slog.w(TAG, "==> For Dynamic broadast");
15131            }
15132            mReceiverResolver.addFilter(bf);
15133
15134            // Enqueue broadcasts for all existing stickies that match
15135            // this filter.
15136            if (allSticky != null) {
15137                ArrayList receivers = new ArrayList();
15138                receivers.add(bf);
15139
15140                int N = allSticky.size();
15141                for (int i=0; i<N; i++) {
15142                    Intent intent = (Intent)allSticky.get(i);
15143                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15144                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15145                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15146                            null, null, false, true, true, -1);
15147                    queue.enqueueParallelBroadcastLocked(r);
15148                    queue.scheduleBroadcastsLocked();
15149                }
15150            }
15151
15152            return sticky;
15153        }
15154    }
15155
15156    public void unregisterReceiver(IIntentReceiver receiver) {
15157        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15158
15159        final long origId = Binder.clearCallingIdentity();
15160        try {
15161            boolean doTrim = false;
15162
15163            synchronized(this) {
15164                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15165                if (rl != null) {
15166                    if (rl.curBroadcast != null) {
15167                        BroadcastRecord r = rl.curBroadcast;
15168                        final boolean doNext = finishReceiverLocked(
15169                                receiver.asBinder(), r.resultCode, r.resultData,
15170                                r.resultExtras, r.resultAbort);
15171                        if (doNext) {
15172                            doTrim = true;
15173                            r.queue.processNextBroadcast(false);
15174                        }
15175                    }
15176
15177                    if (rl.app != null) {
15178                        rl.app.receivers.remove(rl);
15179                    }
15180                    removeReceiverLocked(rl);
15181                    if (rl.linkedToDeath) {
15182                        rl.linkedToDeath = false;
15183                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15184                    }
15185                }
15186            }
15187
15188            // If we actually concluded any broadcasts, we might now be able
15189            // to trim the recipients' apps from our working set
15190            if (doTrim) {
15191                trimApplications();
15192                return;
15193            }
15194
15195        } finally {
15196            Binder.restoreCallingIdentity(origId);
15197        }
15198    }
15199
15200    void removeReceiverLocked(ReceiverList rl) {
15201        mRegisteredReceivers.remove(rl.receiver.asBinder());
15202        int N = rl.size();
15203        for (int i=0; i<N; i++) {
15204            mReceiverResolver.removeFilter(rl.get(i));
15205        }
15206    }
15207
15208    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15209        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15210            ProcessRecord r = mLruProcesses.get(i);
15211            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15212                try {
15213                    r.thread.dispatchPackageBroadcast(cmd, packages);
15214                } catch (RemoteException ex) {
15215                }
15216            }
15217        }
15218    }
15219
15220    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15221            int callingUid, int[] users) {
15222        List<ResolveInfo> receivers = null;
15223        try {
15224            HashSet<ComponentName> singleUserReceivers = null;
15225            boolean scannedFirstReceivers = false;
15226            for (int user : users) {
15227                // Skip users that have Shell restrictions
15228                if (callingUid == Process.SHELL_UID
15229                        && getUserManagerLocked().hasUserRestriction(
15230                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15231                    continue;
15232                }
15233                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15234                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15235                if (user != 0 && newReceivers != null) {
15236                    // If this is not the primary user, we need to check for
15237                    // any receivers that should be filtered out.
15238                    for (int i=0; i<newReceivers.size(); i++) {
15239                        ResolveInfo ri = newReceivers.get(i);
15240                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15241                            newReceivers.remove(i);
15242                            i--;
15243                        }
15244                    }
15245                }
15246                if (newReceivers != null && newReceivers.size() == 0) {
15247                    newReceivers = null;
15248                }
15249                if (receivers == null) {
15250                    receivers = newReceivers;
15251                } else if (newReceivers != null) {
15252                    // We need to concatenate the additional receivers
15253                    // found with what we have do far.  This would be easy,
15254                    // but we also need to de-dup any receivers that are
15255                    // singleUser.
15256                    if (!scannedFirstReceivers) {
15257                        // Collect any single user receivers we had already retrieved.
15258                        scannedFirstReceivers = true;
15259                        for (int i=0; i<receivers.size(); i++) {
15260                            ResolveInfo ri = receivers.get(i);
15261                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15262                                ComponentName cn = new ComponentName(
15263                                        ri.activityInfo.packageName, ri.activityInfo.name);
15264                                if (singleUserReceivers == null) {
15265                                    singleUserReceivers = new HashSet<ComponentName>();
15266                                }
15267                                singleUserReceivers.add(cn);
15268                            }
15269                        }
15270                    }
15271                    // Add the new results to the existing results, tracking
15272                    // and de-dupping single user receivers.
15273                    for (int i=0; i<newReceivers.size(); i++) {
15274                        ResolveInfo ri = newReceivers.get(i);
15275                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15276                            ComponentName cn = new ComponentName(
15277                                    ri.activityInfo.packageName, ri.activityInfo.name);
15278                            if (singleUserReceivers == null) {
15279                                singleUserReceivers = new HashSet<ComponentName>();
15280                            }
15281                            if (!singleUserReceivers.contains(cn)) {
15282                                singleUserReceivers.add(cn);
15283                                receivers.add(ri);
15284                            }
15285                        } else {
15286                            receivers.add(ri);
15287                        }
15288                    }
15289                }
15290            }
15291        } catch (RemoteException ex) {
15292            // pm is in same process, this will never happen.
15293        }
15294        return receivers;
15295    }
15296
15297    private final int broadcastIntentLocked(ProcessRecord callerApp,
15298            String callerPackage, Intent intent, String resolvedType,
15299            IIntentReceiver resultTo, int resultCode, String resultData,
15300            Bundle map, String requiredPermission, int appOp,
15301            boolean ordered, boolean sticky, int callingPid, int callingUid,
15302            int userId) {
15303        intent = new Intent(intent);
15304
15305        // By default broadcasts do not go to stopped apps.
15306        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15307
15308        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15309            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15310            + " ordered=" + ordered + " userid=" + userId);
15311        if ((resultTo != null) && !ordered) {
15312            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15313        }
15314
15315        userId = handleIncomingUser(callingPid, callingUid, userId,
15316                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15317
15318        // Make sure that the user who is receiving this broadcast is started.
15319        // If not, we will just skip it.
15320
15321        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15322            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15323                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15324                Slog.w(TAG, "Skipping broadcast of " + intent
15325                        + ": user " + userId + " is stopped");
15326                return ActivityManager.BROADCAST_SUCCESS;
15327            }
15328        }
15329
15330        /*
15331         * Prevent non-system code (defined here to be non-persistent
15332         * processes) from sending protected broadcasts.
15333         */
15334        int callingAppId = UserHandle.getAppId(callingUid);
15335        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15336            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15337            || callingAppId == Process.NFC_UID || callingUid == 0) {
15338            // Always okay.
15339        } else if (callerApp == null || !callerApp.persistent) {
15340            try {
15341                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15342                        intent.getAction())) {
15343                    String msg = "Permission Denial: not allowed to send broadcast "
15344                            + intent.getAction() + " from pid="
15345                            + callingPid + ", uid=" + callingUid;
15346                    Slog.w(TAG, msg);
15347                    throw new SecurityException(msg);
15348                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15349                    // Special case for compatibility: we don't want apps to send this,
15350                    // but historically it has not been protected and apps may be using it
15351                    // to poke their own app widget.  So, instead of making it protected,
15352                    // just limit it to the caller.
15353                    if (callerApp == null) {
15354                        String msg = "Permission Denial: not allowed to send broadcast "
15355                                + intent.getAction() + " from unknown caller.";
15356                        Slog.w(TAG, msg);
15357                        throw new SecurityException(msg);
15358                    } else if (intent.getComponent() != null) {
15359                        // They are good enough to send to an explicit component...  verify
15360                        // it is being sent to the calling app.
15361                        if (!intent.getComponent().getPackageName().equals(
15362                                callerApp.info.packageName)) {
15363                            String msg = "Permission Denial: not allowed to send broadcast "
15364                                    + intent.getAction() + " to "
15365                                    + intent.getComponent().getPackageName() + " from "
15366                                    + callerApp.info.packageName;
15367                            Slog.w(TAG, msg);
15368                            throw new SecurityException(msg);
15369                        }
15370                    } else {
15371                        // Limit broadcast to their own package.
15372                        intent.setPackage(callerApp.info.packageName);
15373                    }
15374                }
15375            } catch (RemoteException e) {
15376                Slog.w(TAG, "Remote exception", e);
15377                return ActivityManager.BROADCAST_SUCCESS;
15378            }
15379        }
15380
15381        // Handle special intents: if this broadcast is from the package
15382        // manager about a package being removed, we need to remove all of
15383        // its activities from the history stack.
15384        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15385                intent.getAction());
15386        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15387                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15388                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15389                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15390                || uidRemoved) {
15391            if (checkComponentPermission(
15392                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15393                    callingPid, callingUid, -1, true)
15394                    == PackageManager.PERMISSION_GRANTED) {
15395                if (uidRemoved) {
15396                    final Bundle intentExtras = intent.getExtras();
15397                    final int uid = intentExtras != null
15398                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15399                    if (uid >= 0) {
15400                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15401                        synchronized (bs) {
15402                            bs.removeUidStatsLocked(uid);
15403                        }
15404                        mAppOpsService.uidRemoved(uid);
15405                    }
15406                } else {
15407                    // If resources are unavailable just force stop all
15408                    // those packages and flush the attribute cache as well.
15409                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15410                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15411                        if (list != null && (list.length > 0)) {
15412                            for (String pkg : list) {
15413                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15414                                        "storage unmount");
15415                            }
15416                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15417                            sendPackageBroadcastLocked(
15418                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15419                        }
15420                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15421                            intent.getAction())) {
15422                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15423                    } else {
15424                        Uri data = intent.getData();
15425                        String ssp;
15426                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15427                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15428                                    intent.getAction());
15429                            boolean fullUninstall = removed &&
15430                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15431                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15432                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15433                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15434                                        false, fullUninstall, userId,
15435                                        removed ? "pkg removed" : "pkg changed");
15436                            }
15437                            if (removed) {
15438                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15439                                        new String[] {ssp}, userId);
15440                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15441                                    mAppOpsService.packageRemoved(
15442                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15443
15444                                    // Remove all permissions granted from/to this package
15445                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15446                                }
15447                            }
15448                        }
15449                    }
15450                }
15451            } else {
15452                String msg = "Permission Denial: " + intent.getAction()
15453                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15454                        + ", uid=" + callingUid + ")"
15455                        + " requires "
15456                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15457                Slog.w(TAG, msg);
15458                throw new SecurityException(msg);
15459            }
15460
15461        // Special case for adding a package: by default turn on compatibility
15462        // mode.
15463        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15464            Uri data = intent.getData();
15465            String ssp;
15466            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15467                mCompatModePackages.handlePackageAddedLocked(ssp,
15468                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15469            }
15470        }
15471
15472        /*
15473         * If this is the time zone changed action, queue up a message that will reset the timezone
15474         * of all currently running processes. This message will get queued up before the broadcast
15475         * happens.
15476         */
15477        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15478            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15479        }
15480
15481        /*
15482         * If the user set the time, let all running processes know.
15483         */
15484        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15485            final int is24Hour = intent.getBooleanExtra(
15486                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15487            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15488            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15489            synchronized (stats) {
15490                stats.noteCurrentTimeChangedLocked();
15491            }
15492        }
15493
15494        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15495            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15496        }
15497
15498        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15499            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15500            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15501        }
15502
15503        // Add to the sticky list if requested.
15504        if (sticky) {
15505            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15506                    callingPid, callingUid)
15507                    != PackageManager.PERMISSION_GRANTED) {
15508                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15509                        + callingPid + ", uid=" + callingUid
15510                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15511                Slog.w(TAG, msg);
15512                throw new SecurityException(msg);
15513            }
15514            if (requiredPermission != null) {
15515                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15516                        + " and enforce permission " + requiredPermission);
15517                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15518            }
15519            if (intent.getComponent() != null) {
15520                throw new SecurityException(
15521                        "Sticky broadcasts can't target a specific component");
15522            }
15523            // We use userId directly here, since the "all" target is maintained
15524            // as a separate set of sticky broadcasts.
15525            if (userId != UserHandle.USER_ALL) {
15526                // But first, if this is not a broadcast to all users, then
15527                // make sure it doesn't conflict with an existing broadcast to
15528                // all users.
15529                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15530                        UserHandle.USER_ALL);
15531                if (stickies != null) {
15532                    ArrayList<Intent> list = stickies.get(intent.getAction());
15533                    if (list != null) {
15534                        int N = list.size();
15535                        int i;
15536                        for (i=0; i<N; i++) {
15537                            if (intent.filterEquals(list.get(i))) {
15538                                throw new IllegalArgumentException(
15539                                        "Sticky broadcast " + intent + " for user "
15540                                        + userId + " conflicts with existing global broadcast");
15541                            }
15542                        }
15543                    }
15544                }
15545            }
15546            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15547            if (stickies == null) {
15548                stickies = new ArrayMap<String, ArrayList<Intent>>();
15549                mStickyBroadcasts.put(userId, stickies);
15550            }
15551            ArrayList<Intent> list = stickies.get(intent.getAction());
15552            if (list == null) {
15553                list = new ArrayList<Intent>();
15554                stickies.put(intent.getAction(), list);
15555            }
15556            int N = list.size();
15557            int i;
15558            for (i=0; i<N; i++) {
15559                if (intent.filterEquals(list.get(i))) {
15560                    // This sticky already exists, replace it.
15561                    list.set(i, new Intent(intent));
15562                    break;
15563                }
15564            }
15565            if (i >= N) {
15566                list.add(new Intent(intent));
15567            }
15568        }
15569
15570        int[] users;
15571        if (userId == UserHandle.USER_ALL) {
15572            // Caller wants broadcast to go to all started users.
15573            users = mStartedUserArray;
15574        } else {
15575            // Caller wants broadcast to go to one specific user.
15576            users = new int[] {userId};
15577        }
15578
15579        // Figure out who all will receive this broadcast.
15580        List receivers = null;
15581        List<BroadcastFilter> registeredReceivers = null;
15582        // Need to resolve the intent to interested receivers...
15583        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15584                 == 0) {
15585            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15586        }
15587        if (intent.getComponent() == null) {
15588            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15589                // Query one target user at a time, excluding shell-restricted users
15590                UserManagerService ums = getUserManagerLocked();
15591                for (int i = 0; i < users.length; i++) {
15592                    if (ums.hasUserRestriction(
15593                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15594                        continue;
15595                    }
15596                    List<BroadcastFilter> registeredReceiversForUser =
15597                            mReceiverResolver.queryIntent(intent,
15598                                    resolvedType, false, users[i]);
15599                    if (registeredReceivers == null) {
15600                        registeredReceivers = registeredReceiversForUser;
15601                    } else if (registeredReceiversForUser != null) {
15602                        registeredReceivers.addAll(registeredReceiversForUser);
15603                    }
15604                }
15605            } else {
15606                registeredReceivers = mReceiverResolver.queryIntent(intent,
15607                        resolvedType, false, userId);
15608            }
15609        }
15610
15611        final boolean replacePending =
15612                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15613
15614        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15615                + " replacePending=" + replacePending);
15616
15617        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15618        if (!ordered && NR > 0) {
15619            // If we are not serializing this broadcast, then send the
15620            // registered receivers separately so they don't wait for the
15621            // components to be launched.
15622            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15623            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15624                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15625                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15626                    ordered, sticky, false, userId);
15627            if (DEBUG_BROADCAST) Slog.v(
15628                    TAG, "Enqueueing parallel broadcast " + r);
15629            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15630            if (!replaced) {
15631                queue.enqueueParallelBroadcastLocked(r);
15632                queue.scheduleBroadcastsLocked();
15633            }
15634            registeredReceivers = null;
15635            NR = 0;
15636        }
15637
15638        // Merge into one list.
15639        int ir = 0;
15640        if (receivers != null) {
15641            // A special case for PACKAGE_ADDED: do not allow the package
15642            // being added to see this broadcast.  This prevents them from
15643            // using this as a back door to get run as soon as they are
15644            // installed.  Maybe in the future we want to have a special install
15645            // broadcast or such for apps, but we'd like to deliberately make
15646            // this decision.
15647            String skipPackages[] = null;
15648            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15649                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15650                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15651                Uri data = intent.getData();
15652                if (data != null) {
15653                    String pkgName = data.getSchemeSpecificPart();
15654                    if (pkgName != null) {
15655                        skipPackages = new String[] { pkgName };
15656                    }
15657                }
15658            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15659                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15660            }
15661            if (skipPackages != null && (skipPackages.length > 0)) {
15662                for (String skipPackage : skipPackages) {
15663                    if (skipPackage != null) {
15664                        int NT = receivers.size();
15665                        for (int it=0; it<NT; it++) {
15666                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15667                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15668                                receivers.remove(it);
15669                                it--;
15670                                NT--;
15671                            }
15672                        }
15673                    }
15674                }
15675            }
15676
15677            int NT = receivers != null ? receivers.size() : 0;
15678            int it = 0;
15679            ResolveInfo curt = null;
15680            BroadcastFilter curr = null;
15681            while (it < NT && ir < NR) {
15682                if (curt == null) {
15683                    curt = (ResolveInfo)receivers.get(it);
15684                }
15685                if (curr == null) {
15686                    curr = registeredReceivers.get(ir);
15687                }
15688                if (curr.getPriority() >= curt.priority) {
15689                    // Insert this broadcast record into the final list.
15690                    receivers.add(it, curr);
15691                    ir++;
15692                    curr = null;
15693                    it++;
15694                    NT++;
15695                } else {
15696                    // Skip to the next ResolveInfo in the final list.
15697                    it++;
15698                    curt = null;
15699                }
15700            }
15701        }
15702        while (ir < NR) {
15703            if (receivers == null) {
15704                receivers = new ArrayList();
15705            }
15706            receivers.add(registeredReceivers.get(ir));
15707            ir++;
15708        }
15709
15710        if ((receivers != null && receivers.size() > 0)
15711                || resultTo != null) {
15712            BroadcastQueue queue = broadcastQueueForIntent(intent);
15713            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15714                    callerPackage, callingPid, callingUid, resolvedType,
15715                    requiredPermission, appOp, receivers, resultTo, resultCode,
15716                    resultData, map, ordered, sticky, false, userId);
15717            if (DEBUG_BROADCAST) Slog.v(
15718                    TAG, "Enqueueing ordered broadcast " + r
15719                    + ": prev had " + queue.mOrderedBroadcasts.size());
15720            if (DEBUG_BROADCAST) {
15721                int seq = r.intent.getIntExtra("seq", -1);
15722                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15723            }
15724            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15725            if (!replaced) {
15726                queue.enqueueOrderedBroadcastLocked(r);
15727                queue.scheduleBroadcastsLocked();
15728            }
15729        }
15730
15731        return ActivityManager.BROADCAST_SUCCESS;
15732    }
15733
15734    final Intent verifyBroadcastLocked(Intent intent) {
15735        // Refuse possible leaked file descriptors
15736        if (intent != null && intent.hasFileDescriptors() == true) {
15737            throw new IllegalArgumentException("File descriptors passed in Intent");
15738        }
15739
15740        int flags = intent.getFlags();
15741
15742        if (!mProcessesReady) {
15743            // if the caller really truly claims to know what they're doing, go
15744            // ahead and allow the broadcast without launching any receivers
15745            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15746                intent = new Intent(intent);
15747                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15748            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15749                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15750                        + " before boot completion");
15751                throw new IllegalStateException("Cannot broadcast before boot completed");
15752            }
15753        }
15754
15755        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15756            throw new IllegalArgumentException(
15757                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15758        }
15759
15760        return intent;
15761    }
15762
15763    public final int broadcastIntent(IApplicationThread caller,
15764            Intent intent, String resolvedType, IIntentReceiver resultTo,
15765            int resultCode, String resultData, Bundle map,
15766            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15767        enforceNotIsolatedCaller("broadcastIntent");
15768        synchronized(this) {
15769            intent = verifyBroadcastLocked(intent);
15770
15771            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15772            final int callingPid = Binder.getCallingPid();
15773            final int callingUid = Binder.getCallingUid();
15774            final long origId = Binder.clearCallingIdentity();
15775            int res = broadcastIntentLocked(callerApp,
15776                    callerApp != null ? callerApp.info.packageName : null,
15777                    intent, resolvedType, resultTo,
15778                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15779                    callingPid, callingUid, userId);
15780            Binder.restoreCallingIdentity(origId);
15781            return res;
15782        }
15783    }
15784
15785    int broadcastIntentInPackage(String packageName, int uid,
15786            Intent intent, String resolvedType, IIntentReceiver resultTo,
15787            int resultCode, String resultData, Bundle map,
15788            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15789        synchronized(this) {
15790            intent = verifyBroadcastLocked(intent);
15791
15792            final long origId = Binder.clearCallingIdentity();
15793            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15794                    resultTo, resultCode, resultData, map, requiredPermission,
15795                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15796            Binder.restoreCallingIdentity(origId);
15797            return res;
15798        }
15799    }
15800
15801    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15802        // Refuse possible leaked file descriptors
15803        if (intent != null && intent.hasFileDescriptors() == true) {
15804            throw new IllegalArgumentException("File descriptors passed in Intent");
15805        }
15806
15807        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15808                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15809
15810        synchronized(this) {
15811            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15812                    != PackageManager.PERMISSION_GRANTED) {
15813                String msg = "Permission Denial: unbroadcastIntent() from pid="
15814                        + Binder.getCallingPid()
15815                        + ", uid=" + Binder.getCallingUid()
15816                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15817                Slog.w(TAG, msg);
15818                throw new SecurityException(msg);
15819            }
15820            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15821            if (stickies != null) {
15822                ArrayList<Intent> list = stickies.get(intent.getAction());
15823                if (list != null) {
15824                    int N = list.size();
15825                    int i;
15826                    for (i=0; i<N; i++) {
15827                        if (intent.filterEquals(list.get(i))) {
15828                            list.remove(i);
15829                            break;
15830                        }
15831                    }
15832                    if (list.size() <= 0) {
15833                        stickies.remove(intent.getAction());
15834                    }
15835                }
15836                if (stickies.size() <= 0) {
15837                    mStickyBroadcasts.remove(userId);
15838                }
15839            }
15840        }
15841    }
15842
15843    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15844            String resultData, Bundle resultExtras, boolean resultAbort) {
15845        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15846        if (r == null) {
15847            Slog.w(TAG, "finishReceiver called but not found on queue");
15848            return false;
15849        }
15850
15851        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15852    }
15853
15854    void backgroundServicesFinishedLocked(int userId) {
15855        for (BroadcastQueue queue : mBroadcastQueues) {
15856            queue.backgroundServicesFinishedLocked(userId);
15857        }
15858    }
15859
15860    public void finishReceiver(IBinder who, int resultCode, String resultData,
15861            Bundle resultExtras, boolean resultAbort) {
15862        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15863
15864        // Refuse possible leaked file descriptors
15865        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15866            throw new IllegalArgumentException("File descriptors passed in Bundle");
15867        }
15868
15869        final long origId = Binder.clearCallingIdentity();
15870        try {
15871            boolean doNext = false;
15872            BroadcastRecord r;
15873
15874            synchronized(this) {
15875                r = broadcastRecordForReceiverLocked(who);
15876                if (r != null) {
15877                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15878                        resultData, resultExtras, resultAbort, true);
15879                }
15880            }
15881
15882            if (doNext) {
15883                r.queue.processNextBroadcast(false);
15884            }
15885            trimApplications();
15886        } finally {
15887            Binder.restoreCallingIdentity(origId);
15888        }
15889    }
15890
15891    // =========================================================
15892    // INSTRUMENTATION
15893    // =========================================================
15894
15895    public boolean startInstrumentation(ComponentName className,
15896            String profileFile, int flags, Bundle arguments,
15897            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15898            int userId, String abiOverride) {
15899        enforceNotIsolatedCaller("startInstrumentation");
15900        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15901                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15902        // Refuse possible leaked file descriptors
15903        if (arguments != null && arguments.hasFileDescriptors()) {
15904            throw new IllegalArgumentException("File descriptors passed in Bundle");
15905        }
15906
15907        synchronized(this) {
15908            InstrumentationInfo ii = null;
15909            ApplicationInfo ai = null;
15910            try {
15911                ii = mContext.getPackageManager().getInstrumentationInfo(
15912                    className, STOCK_PM_FLAGS);
15913                ai = AppGlobals.getPackageManager().getApplicationInfo(
15914                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15915            } catch (PackageManager.NameNotFoundException e) {
15916            } catch (RemoteException e) {
15917            }
15918            if (ii == null) {
15919                reportStartInstrumentationFailure(watcher, className,
15920                        "Unable to find instrumentation info for: " + className);
15921                return false;
15922            }
15923            if (ai == null) {
15924                reportStartInstrumentationFailure(watcher, className,
15925                        "Unable to find instrumentation target package: " + ii.targetPackage);
15926                return false;
15927            }
15928
15929            int match = mContext.getPackageManager().checkSignatures(
15930                    ii.targetPackage, ii.packageName);
15931            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15932                String msg = "Permission Denial: starting instrumentation "
15933                        + className + " from pid="
15934                        + Binder.getCallingPid()
15935                        + ", uid=" + Binder.getCallingPid()
15936                        + " not allowed because package " + ii.packageName
15937                        + " does not have a signature matching the target "
15938                        + ii.targetPackage;
15939                reportStartInstrumentationFailure(watcher, className, msg);
15940                throw new SecurityException(msg);
15941            }
15942
15943            final long origId = Binder.clearCallingIdentity();
15944            // Instrumentation can kill and relaunch even persistent processes
15945            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15946                    "start instr");
15947            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15948            app.instrumentationClass = className;
15949            app.instrumentationInfo = ai;
15950            app.instrumentationProfileFile = profileFile;
15951            app.instrumentationArguments = arguments;
15952            app.instrumentationWatcher = watcher;
15953            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15954            app.instrumentationResultClass = className;
15955            Binder.restoreCallingIdentity(origId);
15956        }
15957
15958        return true;
15959    }
15960
15961    /**
15962     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15963     * error to the logs, but if somebody is watching, send the report there too.  This enables
15964     * the "am" command to report errors with more information.
15965     *
15966     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15967     * @param cn The component name of the instrumentation.
15968     * @param report The error report.
15969     */
15970    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15971            ComponentName cn, String report) {
15972        Slog.w(TAG, report);
15973        try {
15974            if (watcher != null) {
15975                Bundle results = new Bundle();
15976                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15977                results.putString("Error", report);
15978                watcher.instrumentationStatus(cn, -1, results);
15979            }
15980        } catch (RemoteException e) {
15981            Slog.w(TAG, e);
15982        }
15983    }
15984
15985    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15986        if (app.instrumentationWatcher != null) {
15987            try {
15988                // NOTE:  IInstrumentationWatcher *must* be oneway here
15989                app.instrumentationWatcher.instrumentationFinished(
15990                    app.instrumentationClass,
15991                    resultCode,
15992                    results);
15993            } catch (RemoteException e) {
15994            }
15995        }
15996        if (app.instrumentationUiAutomationConnection != null) {
15997            try {
15998                app.instrumentationUiAutomationConnection.shutdown();
15999            } catch (RemoteException re) {
16000                /* ignore */
16001            }
16002            // Only a UiAutomation can set this flag and now that
16003            // it is finished we make sure it is reset to its default.
16004            mUserIsMonkey = false;
16005        }
16006        app.instrumentationWatcher = null;
16007        app.instrumentationUiAutomationConnection = null;
16008        app.instrumentationClass = null;
16009        app.instrumentationInfo = null;
16010        app.instrumentationProfileFile = null;
16011        app.instrumentationArguments = null;
16012
16013        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16014                "finished inst");
16015    }
16016
16017    public void finishInstrumentation(IApplicationThread target,
16018            int resultCode, Bundle results) {
16019        int userId = UserHandle.getCallingUserId();
16020        // Refuse possible leaked file descriptors
16021        if (results != null && results.hasFileDescriptors()) {
16022            throw new IllegalArgumentException("File descriptors passed in Intent");
16023        }
16024
16025        synchronized(this) {
16026            ProcessRecord app = getRecordForAppLocked(target);
16027            if (app == null) {
16028                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16029                return;
16030            }
16031            final long origId = Binder.clearCallingIdentity();
16032            finishInstrumentationLocked(app, resultCode, results);
16033            Binder.restoreCallingIdentity(origId);
16034        }
16035    }
16036
16037    // =========================================================
16038    // CONFIGURATION
16039    // =========================================================
16040
16041    public ConfigurationInfo getDeviceConfigurationInfo() {
16042        ConfigurationInfo config = new ConfigurationInfo();
16043        synchronized (this) {
16044            config.reqTouchScreen = mConfiguration.touchscreen;
16045            config.reqKeyboardType = mConfiguration.keyboard;
16046            config.reqNavigation = mConfiguration.navigation;
16047            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16048                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16049                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16050            }
16051            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16052                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16053                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16054            }
16055            config.reqGlEsVersion = GL_ES_VERSION;
16056        }
16057        return config;
16058    }
16059
16060    ActivityStack getFocusedStack() {
16061        return mStackSupervisor.getFocusedStack();
16062    }
16063
16064    public Configuration getConfiguration() {
16065        Configuration ci;
16066        synchronized(this) {
16067            ci = new Configuration(mConfiguration);
16068        }
16069        return ci;
16070    }
16071
16072    public void updatePersistentConfiguration(Configuration values) {
16073        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16074                "updateConfiguration()");
16075        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16076                "updateConfiguration()");
16077        if (values == null) {
16078            throw new NullPointerException("Configuration must not be null");
16079        }
16080
16081        synchronized(this) {
16082            final long origId = Binder.clearCallingIdentity();
16083            updateConfigurationLocked(values, null, true, false);
16084            Binder.restoreCallingIdentity(origId);
16085        }
16086    }
16087
16088    public void updateConfiguration(Configuration values) {
16089        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16090                "updateConfiguration()");
16091
16092        synchronized(this) {
16093            if (values == null && mWindowManager != null) {
16094                // sentinel: fetch the current configuration from the window manager
16095                values = mWindowManager.computeNewConfiguration();
16096            }
16097
16098            if (mWindowManager != null) {
16099                mProcessList.applyDisplaySize(mWindowManager);
16100            }
16101
16102            final long origId = Binder.clearCallingIdentity();
16103            if (values != null) {
16104                Settings.System.clearConfiguration(values);
16105            }
16106            updateConfigurationLocked(values, null, false, false);
16107            Binder.restoreCallingIdentity(origId);
16108        }
16109    }
16110
16111    /**
16112     * Do either or both things: (1) change the current configuration, and (2)
16113     * make sure the given activity is running with the (now) current
16114     * configuration.  Returns true if the activity has been left running, or
16115     * false if <var>starting</var> is being destroyed to match the new
16116     * configuration.
16117     * @param persistent TODO
16118     */
16119    boolean updateConfigurationLocked(Configuration values,
16120            ActivityRecord starting, boolean persistent, boolean initLocale) {
16121        int changes = 0;
16122
16123        if (values != null) {
16124            Configuration newConfig = new Configuration(mConfiguration);
16125            changes = newConfig.updateFrom(values);
16126            if (changes != 0) {
16127                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16128                    Slog.i(TAG, "Updating configuration to: " + values);
16129                }
16130
16131                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16132
16133                if (values.locale != null && !initLocale) {
16134                    saveLocaleLocked(values.locale,
16135                                     !values.locale.equals(mConfiguration.locale),
16136                                     values.userSetLocale);
16137                }
16138
16139                mConfigurationSeq++;
16140                if (mConfigurationSeq <= 0) {
16141                    mConfigurationSeq = 1;
16142                }
16143                newConfig.seq = mConfigurationSeq;
16144                mConfiguration = newConfig;
16145                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16146                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16147                //mUsageStatsService.noteStartConfig(newConfig);
16148
16149                final Configuration configCopy = new Configuration(mConfiguration);
16150
16151                // TODO: If our config changes, should we auto dismiss any currently
16152                // showing dialogs?
16153                mShowDialogs = shouldShowDialogs(newConfig);
16154
16155                AttributeCache ac = AttributeCache.instance();
16156                if (ac != null) {
16157                    ac.updateConfiguration(configCopy);
16158                }
16159
16160                // Make sure all resources in our process are updated
16161                // right now, so that anyone who is going to retrieve
16162                // resource values after we return will be sure to get
16163                // the new ones.  This is especially important during
16164                // boot, where the first config change needs to guarantee
16165                // all resources have that config before following boot
16166                // code is executed.
16167                mSystemThread.applyConfigurationToResources(configCopy);
16168
16169                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16170                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16171                    msg.obj = new Configuration(configCopy);
16172                    mHandler.sendMessage(msg);
16173                }
16174
16175                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16176                    ProcessRecord app = mLruProcesses.get(i);
16177                    try {
16178                        if (app.thread != null) {
16179                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16180                                    + app.processName + " new config " + mConfiguration);
16181                            app.thread.scheduleConfigurationChanged(configCopy);
16182                        }
16183                    } catch (Exception e) {
16184                    }
16185                }
16186                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16187                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16188                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16189                        | Intent.FLAG_RECEIVER_FOREGROUND);
16190                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16191                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16192                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16193                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16194                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16195                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16196                    broadcastIntentLocked(null, null, intent,
16197                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16198                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16199                }
16200            }
16201        }
16202
16203        boolean kept = true;
16204        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16205        // mainStack is null during startup.
16206        if (mainStack != null) {
16207            if (changes != 0 && starting == null) {
16208                // If the configuration changed, and the caller is not already
16209                // in the process of starting an activity, then find the top
16210                // activity to check if its configuration needs to change.
16211                starting = mainStack.topRunningActivityLocked(null);
16212            }
16213
16214            if (starting != null) {
16215                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16216                // And we need to make sure at this point that all other activities
16217                // are made visible with the correct configuration.
16218                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16219            }
16220        }
16221
16222        if (values != null && mWindowManager != null) {
16223            mWindowManager.setNewConfiguration(mConfiguration);
16224        }
16225
16226        return kept;
16227    }
16228
16229    /**
16230     * Decide based on the configuration whether we should shouw the ANR,
16231     * crash, etc dialogs.  The idea is that if there is no affordnace to
16232     * press the on-screen buttons, we shouldn't show the dialog.
16233     *
16234     * A thought: SystemUI might also want to get told about this, the Power
16235     * dialog / global actions also might want different behaviors.
16236     */
16237    private static final boolean shouldShowDialogs(Configuration config) {
16238        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16239                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16240    }
16241
16242    /**
16243     * Save the locale.  You must be inside a synchronized (this) block.
16244     */
16245    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16246        if(isDiff) {
16247            SystemProperties.set("user.language", l.getLanguage());
16248            SystemProperties.set("user.region", l.getCountry());
16249        }
16250
16251        if(isPersist) {
16252            SystemProperties.set("persist.sys.language", l.getLanguage());
16253            SystemProperties.set("persist.sys.country", l.getCountry());
16254            SystemProperties.set("persist.sys.localevar", l.getVariant());
16255        }
16256    }
16257
16258    @Override
16259    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16260        synchronized (this) {
16261            ActivityRecord srec = ActivityRecord.forToken(token);
16262            if (srec.task != null && srec.task.stack != null) {
16263                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16264            }
16265        }
16266        return false;
16267    }
16268
16269    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16270            Intent resultData) {
16271
16272        synchronized (this) {
16273            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16274            if (stack != null) {
16275                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16276            }
16277            return false;
16278        }
16279    }
16280
16281    public int getLaunchedFromUid(IBinder activityToken) {
16282        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16283        if (srec == null) {
16284            return -1;
16285        }
16286        return srec.launchedFromUid;
16287    }
16288
16289    public String getLaunchedFromPackage(IBinder activityToken) {
16290        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16291        if (srec == null) {
16292            return null;
16293        }
16294        return srec.launchedFromPackage;
16295    }
16296
16297    // =========================================================
16298    // LIFETIME MANAGEMENT
16299    // =========================================================
16300
16301    // Returns which broadcast queue the app is the current [or imminent] receiver
16302    // on, or 'null' if the app is not an active broadcast recipient.
16303    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16304        BroadcastRecord r = app.curReceiver;
16305        if (r != null) {
16306            return r.queue;
16307        }
16308
16309        // It's not the current receiver, but it might be starting up to become one
16310        synchronized (this) {
16311            for (BroadcastQueue queue : mBroadcastQueues) {
16312                r = queue.mPendingBroadcast;
16313                if (r != null && r.curApp == app) {
16314                    // found it; report which queue it's in
16315                    return queue;
16316                }
16317            }
16318        }
16319
16320        return null;
16321    }
16322
16323    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16324            boolean doingAll, long now) {
16325        if (mAdjSeq == app.adjSeq) {
16326            // This adjustment has already been computed.
16327            return app.curRawAdj;
16328        }
16329
16330        if (app.thread == null) {
16331            app.adjSeq = mAdjSeq;
16332            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16333            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16334            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16335        }
16336
16337        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16338        app.adjSource = null;
16339        app.adjTarget = null;
16340        app.empty = false;
16341        app.cached = false;
16342
16343        final int activitiesSize = app.activities.size();
16344
16345        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16346            // The max adjustment doesn't allow this app to be anything
16347            // below foreground, so it is not worth doing work for it.
16348            app.adjType = "fixed";
16349            app.adjSeq = mAdjSeq;
16350            app.curRawAdj = app.maxAdj;
16351            app.foregroundActivities = false;
16352            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16353            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16354            // System processes can do UI, and when they do we want to have
16355            // them trim their memory after the user leaves the UI.  To
16356            // facilitate this, here we need to determine whether or not it
16357            // is currently showing UI.
16358            app.systemNoUi = true;
16359            if (app == TOP_APP) {
16360                app.systemNoUi = false;
16361            } else if (activitiesSize > 0) {
16362                for (int j = 0; j < activitiesSize; j++) {
16363                    final ActivityRecord r = app.activities.get(j);
16364                    if (r.visible) {
16365                        app.systemNoUi = false;
16366                    }
16367                }
16368            }
16369            if (!app.systemNoUi) {
16370                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16371            }
16372            return (app.curAdj=app.maxAdj);
16373        }
16374
16375        app.systemNoUi = false;
16376
16377        // Determine the importance of the process, starting with most
16378        // important to least, and assign an appropriate OOM adjustment.
16379        int adj;
16380        int schedGroup;
16381        int procState;
16382        boolean foregroundActivities = false;
16383        BroadcastQueue queue;
16384        if (app == TOP_APP) {
16385            // The last app on the list is the foreground app.
16386            adj = ProcessList.FOREGROUND_APP_ADJ;
16387            schedGroup = Process.THREAD_GROUP_DEFAULT;
16388            app.adjType = "top-activity";
16389            foregroundActivities = true;
16390            procState = ActivityManager.PROCESS_STATE_TOP;
16391        } else if (app.instrumentationClass != null) {
16392            // Don't want to kill running instrumentation.
16393            adj = ProcessList.FOREGROUND_APP_ADJ;
16394            schedGroup = Process.THREAD_GROUP_DEFAULT;
16395            app.adjType = "instrumentation";
16396            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16397        } else if ((queue = isReceivingBroadcast(app)) != null) {
16398            // An app that is currently receiving a broadcast also
16399            // counts as being in the foreground for OOM killer purposes.
16400            // It's placed in a sched group based on the nature of the
16401            // broadcast as reflected by which queue it's active in.
16402            adj = ProcessList.FOREGROUND_APP_ADJ;
16403            schedGroup = (queue == mFgBroadcastQueue)
16404                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16405            app.adjType = "broadcast";
16406            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16407        } else if (app.executingServices.size() > 0) {
16408            // An app that is currently executing a service callback also
16409            // counts as being in the foreground.
16410            adj = ProcessList.FOREGROUND_APP_ADJ;
16411            schedGroup = app.execServicesFg ?
16412                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16413            app.adjType = "exec-service";
16414            procState = ActivityManager.PROCESS_STATE_SERVICE;
16415            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16416        } else {
16417            // As far as we know the process is empty.  We may change our mind later.
16418            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16419            // At this point we don't actually know the adjustment.  Use the cached adj
16420            // value that the caller wants us to.
16421            adj = cachedAdj;
16422            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16423            app.cached = true;
16424            app.empty = true;
16425            app.adjType = "cch-empty";
16426        }
16427
16428        // Examine all activities if not already foreground.
16429        if (!foregroundActivities && activitiesSize > 0) {
16430            for (int j = 0; j < activitiesSize; j++) {
16431                final ActivityRecord r = app.activities.get(j);
16432                if (r.app != app) {
16433                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16434                            + app + "?!?");
16435                    continue;
16436                }
16437                if (r.visible) {
16438                    // App has a visible activity; only upgrade adjustment.
16439                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16440                        adj = ProcessList.VISIBLE_APP_ADJ;
16441                        app.adjType = "visible";
16442                    }
16443                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16444                        procState = ActivityManager.PROCESS_STATE_TOP;
16445                    }
16446                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16447                    app.cached = false;
16448                    app.empty = false;
16449                    foregroundActivities = true;
16450                    break;
16451                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16452                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16453                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16454                        app.adjType = "pausing";
16455                    }
16456                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16457                        procState = ActivityManager.PROCESS_STATE_TOP;
16458                    }
16459                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16460                    app.cached = false;
16461                    app.empty = false;
16462                    foregroundActivities = true;
16463                } else if (r.state == ActivityState.STOPPING) {
16464                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16465                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16466                        app.adjType = "stopping";
16467                    }
16468                    // For the process state, we will at this point consider the
16469                    // process to be cached.  It will be cached either as an activity
16470                    // or empty depending on whether the activity is finishing.  We do
16471                    // this so that we can treat the process as cached for purposes of
16472                    // memory trimming (determing current memory level, trim command to
16473                    // send to process) since there can be an arbitrary number of stopping
16474                    // processes and they should soon all go into the cached state.
16475                    if (!r.finishing) {
16476                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16477                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16478                        }
16479                    }
16480                    app.cached = false;
16481                    app.empty = false;
16482                    foregroundActivities = true;
16483                } else {
16484                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16485                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16486                        app.adjType = "cch-act";
16487                    }
16488                }
16489            }
16490        }
16491
16492        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16493            if (app.foregroundServices) {
16494                // The user is aware of this app, so make it visible.
16495                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16496                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16497                app.cached = false;
16498                app.adjType = "fg-service";
16499                schedGroup = Process.THREAD_GROUP_DEFAULT;
16500            } else if (app.forcingToForeground != null) {
16501                // The user is aware of this app, so make it visible.
16502                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16503                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16504                app.cached = false;
16505                app.adjType = "force-fg";
16506                app.adjSource = app.forcingToForeground;
16507                schedGroup = Process.THREAD_GROUP_DEFAULT;
16508            }
16509        }
16510
16511        if (app == mHeavyWeightProcess) {
16512            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16513                // We don't want to kill the current heavy-weight process.
16514                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16515                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16516                app.cached = false;
16517                app.adjType = "heavy";
16518            }
16519            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16520                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16521            }
16522        }
16523
16524        if (app == mHomeProcess) {
16525            if (adj > ProcessList.HOME_APP_ADJ) {
16526                // This process is hosting what we currently consider to be the
16527                // home app, so we don't want to let it go into the background.
16528                adj = ProcessList.HOME_APP_ADJ;
16529                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16530                app.cached = false;
16531                app.adjType = "home";
16532            }
16533            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16534                procState = ActivityManager.PROCESS_STATE_HOME;
16535            }
16536        }
16537
16538        if (app == mPreviousProcess && app.activities.size() > 0) {
16539            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16540                // This was the previous process that showed UI to the user.
16541                // We want to try to keep it around more aggressively, to give
16542                // a good experience around switching between two apps.
16543                adj = ProcessList.PREVIOUS_APP_ADJ;
16544                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16545                app.cached = false;
16546                app.adjType = "previous";
16547            }
16548            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16549                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16550            }
16551        }
16552
16553        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16554                + " reason=" + app.adjType);
16555
16556        // By default, we use the computed adjustment.  It may be changed if
16557        // there are applications dependent on our services or providers, but
16558        // this gives us a baseline and makes sure we don't get into an
16559        // infinite recursion.
16560        app.adjSeq = mAdjSeq;
16561        app.curRawAdj = adj;
16562        app.hasStartedServices = false;
16563
16564        if (mBackupTarget != null && app == mBackupTarget.app) {
16565            // If possible we want to avoid killing apps while they're being backed up
16566            if (adj > ProcessList.BACKUP_APP_ADJ) {
16567                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16568                adj = ProcessList.BACKUP_APP_ADJ;
16569                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16570                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16571                }
16572                app.adjType = "backup";
16573                app.cached = false;
16574            }
16575            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16576                procState = ActivityManager.PROCESS_STATE_BACKUP;
16577            }
16578        }
16579
16580        boolean mayBeTop = false;
16581
16582        for (int is = app.services.size()-1;
16583                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16584                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16585                        || procState > ActivityManager.PROCESS_STATE_TOP);
16586                is--) {
16587            ServiceRecord s = app.services.valueAt(is);
16588            if (s.startRequested) {
16589                app.hasStartedServices = true;
16590                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16591                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16592                }
16593                if (app.hasShownUi && app != mHomeProcess) {
16594                    // If this process has shown some UI, let it immediately
16595                    // go to the LRU list because it may be pretty heavy with
16596                    // UI stuff.  We'll tag it with a label just to help
16597                    // debug and understand what is going on.
16598                    if (adj > ProcessList.SERVICE_ADJ) {
16599                        app.adjType = "cch-started-ui-services";
16600                    }
16601                } else {
16602                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16603                        // This service has seen some activity within
16604                        // recent memory, so we will keep its process ahead
16605                        // of the background processes.
16606                        if (adj > ProcessList.SERVICE_ADJ) {
16607                            adj = ProcessList.SERVICE_ADJ;
16608                            app.adjType = "started-services";
16609                            app.cached = false;
16610                        }
16611                    }
16612                    // If we have let the service slide into the background
16613                    // state, still have some text describing what it is doing
16614                    // even though the service no longer has an impact.
16615                    if (adj > ProcessList.SERVICE_ADJ) {
16616                        app.adjType = "cch-started-services";
16617                    }
16618                }
16619            }
16620            for (int conni = s.connections.size()-1;
16621                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16622                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16623                            || procState > ActivityManager.PROCESS_STATE_TOP);
16624                    conni--) {
16625                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16626                for (int i = 0;
16627                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16628                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16629                                || procState > ActivityManager.PROCESS_STATE_TOP);
16630                        i++) {
16631                    // XXX should compute this based on the max of
16632                    // all connected clients.
16633                    ConnectionRecord cr = clist.get(i);
16634                    if (cr.binding.client == app) {
16635                        // Binding to ourself is not interesting.
16636                        continue;
16637                    }
16638                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16639                        ProcessRecord client = cr.binding.client;
16640                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16641                                TOP_APP, doingAll, now);
16642                        int clientProcState = client.curProcState;
16643                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16644                            // If the other app is cached for any reason, for purposes here
16645                            // we are going to consider it empty.  The specific cached state
16646                            // doesn't propagate except under certain conditions.
16647                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16648                        }
16649                        String adjType = null;
16650                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16651                            // Not doing bind OOM management, so treat
16652                            // this guy more like a started service.
16653                            if (app.hasShownUi && app != mHomeProcess) {
16654                                // If this process has shown some UI, let it immediately
16655                                // go to the LRU list because it may be pretty heavy with
16656                                // UI stuff.  We'll tag it with a label just to help
16657                                // debug and understand what is going on.
16658                                if (adj > clientAdj) {
16659                                    adjType = "cch-bound-ui-services";
16660                                }
16661                                app.cached = false;
16662                                clientAdj = adj;
16663                                clientProcState = procState;
16664                            } else {
16665                                if (now >= (s.lastActivity
16666                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16667                                    // This service has not seen activity within
16668                                    // recent memory, so allow it to drop to the
16669                                    // LRU list if there is no other reason to keep
16670                                    // it around.  We'll also tag it with a label just
16671                                    // to help debug and undertand what is going on.
16672                                    if (adj > clientAdj) {
16673                                        adjType = "cch-bound-services";
16674                                    }
16675                                    clientAdj = adj;
16676                                }
16677                            }
16678                        }
16679                        if (adj > clientAdj) {
16680                            // If this process has recently shown UI, and
16681                            // the process that is binding to it is less
16682                            // important than being visible, then we don't
16683                            // care about the binding as much as we care
16684                            // about letting this process get into the LRU
16685                            // list to be killed and restarted if needed for
16686                            // memory.
16687                            if (app.hasShownUi && app != mHomeProcess
16688                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16689                                adjType = "cch-bound-ui-services";
16690                            } else {
16691                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16692                                        |Context.BIND_IMPORTANT)) != 0) {
16693                                    adj = clientAdj;
16694                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16695                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16696                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16697                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16698                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16699                                    adj = clientAdj;
16700                                } else {
16701                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16702                                        adj = ProcessList.VISIBLE_APP_ADJ;
16703                                    }
16704                                }
16705                                if (!client.cached) {
16706                                    app.cached = false;
16707                                }
16708                                adjType = "service";
16709                            }
16710                        }
16711                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16712                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16713                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16714                            }
16715                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16716                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16717                                    // Special handling of clients who are in the top state.
16718                                    // We *may* want to consider this process to be in the
16719                                    // top state as well, but only if there is not another
16720                                    // reason for it to be running.  Being on the top is a
16721                                    // special state, meaning you are specifically running
16722                                    // for the current top app.  If the process is already
16723                                    // running in the background for some other reason, it
16724                                    // is more important to continue considering it to be
16725                                    // in the background state.
16726                                    mayBeTop = true;
16727                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16728                                } else {
16729                                    // Special handling for above-top states (persistent
16730                                    // processes).  These should not bring the current process
16731                                    // into the top state, since they are not on top.  Instead
16732                                    // give them the best state after that.
16733                                    clientProcState =
16734                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16735                                }
16736                            }
16737                        } else {
16738                            if (clientProcState <
16739                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16740                                clientProcState =
16741                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16742                            }
16743                        }
16744                        if (procState > clientProcState) {
16745                            procState = clientProcState;
16746                        }
16747                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16748                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16749                            app.pendingUiClean = true;
16750                        }
16751                        if (adjType != null) {
16752                            app.adjType = adjType;
16753                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16754                                    .REASON_SERVICE_IN_USE;
16755                            app.adjSource = cr.binding.client;
16756                            app.adjSourceProcState = clientProcState;
16757                            app.adjTarget = s.name;
16758                        }
16759                    }
16760                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16761                        app.treatLikeActivity = true;
16762                    }
16763                    final ActivityRecord a = cr.activity;
16764                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16765                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16766                                (a.visible || a.state == ActivityState.RESUMED
16767                                 || a.state == ActivityState.PAUSING)) {
16768                            adj = ProcessList.FOREGROUND_APP_ADJ;
16769                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16770                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16771                            }
16772                            app.cached = false;
16773                            app.adjType = "service";
16774                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16775                                    .REASON_SERVICE_IN_USE;
16776                            app.adjSource = a;
16777                            app.adjSourceProcState = procState;
16778                            app.adjTarget = s.name;
16779                        }
16780                    }
16781                }
16782            }
16783        }
16784
16785        for (int provi = app.pubProviders.size()-1;
16786                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16787                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16788                        || procState > ActivityManager.PROCESS_STATE_TOP);
16789                provi--) {
16790            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16791            for (int i = cpr.connections.size()-1;
16792                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16793                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16794                            || procState > ActivityManager.PROCESS_STATE_TOP);
16795                    i--) {
16796                ContentProviderConnection conn = cpr.connections.get(i);
16797                ProcessRecord client = conn.client;
16798                if (client == app) {
16799                    // Being our own client is not interesting.
16800                    continue;
16801                }
16802                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16803                int clientProcState = client.curProcState;
16804                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16805                    // If the other app is cached for any reason, for purposes here
16806                    // we are going to consider it empty.
16807                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16808                }
16809                if (adj > clientAdj) {
16810                    if (app.hasShownUi && app != mHomeProcess
16811                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16812                        app.adjType = "cch-ui-provider";
16813                    } else {
16814                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16815                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16816                        app.adjType = "provider";
16817                    }
16818                    app.cached &= client.cached;
16819                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16820                            .REASON_PROVIDER_IN_USE;
16821                    app.adjSource = client;
16822                    app.adjSourceProcState = clientProcState;
16823                    app.adjTarget = cpr.name;
16824                }
16825                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16826                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16827                        // Special handling of clients who are in the top state.
16828                        // We *may* want to consider this process to be in the
16829                        // top state as well, but only if there is not another
16830                        // reason for it to be running.  Being on the top is a
16831                        // special state, meaning you are specifically running
16832                        // for the current top app.  If the process is already
16833                        // running in the background for some other reason, it
16834                        // is more important to continue considering it to be
16835                        // in the background state.
16836                        mayBeTop = true;
16837                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16838                    } else {
16839                        // Special handling for above-top states (persistent
16840                        // processes).  These should not bring the current process
16841                        // into the top state, since they are not on top.  Instead
16842                        // give them the best state after that.
16843                        clientProcState =
16844                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16845                    }
16846                }
16847                if (procState > clientProcState) {
16848                    procState = clientProcState;
16849                }
16850                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16851                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16852                }
16853            }
16854            // If the provider has external (non-framework) process
16855            // dependencies, ensure that its adjustment is at least
16856            // FOREGROUND_APP_ADJ.
16857            if (cpr.hasExternalProcessHandles()) {
16858                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16859                    adj = ProcessList.FOREGROUND_APP_ADJ;
16860                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16861                    app.cached = false;
16862                    app.adjType = "provider";
16863                    app.adjTarget = cpr.name;
16864                }
16865                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16866                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16867                }
16868            }
16869        }
16870
16871        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16872            // A client of one of our services or providers is in the top state.  We
16873            // *may* want to be in the top state, but not if we are already running in
16874            // the background for some other reason.  For the decision here, we are going
16875            // to pick out a few specific states that we want to remain in when a client
16876            // is top (states that tend to be longer-term) and otherwise allow it to go
16877            // to the top state.
16878            switch (procState) {
16879                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16880                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16881                case ActivityManager.PROCESS_STATE_SERVICE:
16882                    // These all are longer-term states, so pull them up to the top
16883                    // of the background states, but not all the way to the top state.
16884                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16885                    break;
16886                default:
16887                    // Otherwise, top is a better choice, so take it.
16888                    procState = ActivityManager.PROCESS_STATE_TOP;
16889                    break;
16890            }
16891        }
16892
16893        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16894            if (app.hasClientActivities) {
16895                // This is a cached process, but with client activities.  Mark it so.
16896                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16897                app.adjType = "cch-client-act";
16898            } else if (app.treatLikeActivity) {
16899                // This is a cached process, but somebody wants us to treat it like it has
16900                // an activity, okay!
16901                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16902                app.adjType = "cch-as-act";
16903            }
16904        }
16905
16906        if (adj == ProcessList.SERVICE_ADJ) {
16907            if (doingAll) {
16908                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16909                mNewNumServiceProcs++;
16910                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16911                if (!app.serviceb) {
16912                    // This service isn't far enough down on the LRU list to
16913                    // normally be a B service, but if we are low on RAM and it
16914                    // is large we want to force it down since we would prefer to
16915                    // keep launcher over it.
16916                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16917                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16918                        app.serviceHighRam = true;
16919                        app.serviceb = true;
16920                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16921                    } else {
16922                        mNewNumAServiceProcs++;
16923                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16924                    }
16925                } else {
16926                    app.serviceHighRam = false;
16927                }
16928            }
16929            if (app.serviceb) {
16930                adj = ProcessList.SERVICE_B_ADJ;
16931            }
16932        }
16933
16934        app.curRawAdj = adj;
16935
16936        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16937        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16938        if (adj > app.maxAdj) {
16939            adj = app.maxAdj;
16940            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16941                schedGroup = Process.THREAD_GROUP_DEFAULT;
16942            }
16943        }
16944
16945        // Do final modification to adj.  Everything we do between here and applying
16946        // the final setAdj must be done in this function, because we will also use
16947        // it when computing the final cached adj later.  Note that we don't need to
16948        // worry about this for max adj above, since max adj will always be used to
16949        // keep it out of the cached vaues.
16950        app.curAdj = app.modifyRawOomAdj(adj);
16951        app.curSchedGroup = schedGroup;
16952        app.curProcState = procState;
16953        app.foregroundActivities = foregroundActivities;
16954
16955        return app.curRawAdj;
16956    }
16957
16958    /**
16959     * Schedule PSS collection of a process.
16960     */
16961    void requestPssLocked(ProcessRecord proc, int procState) {
16962        if (mPendingPssProcesses.contains(proc)) {
16963            return;
16964        }
16965        if (mPendingPssProcesses.size() == 0) {
16966            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16967        }
16968        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16969        proc.pssProcState = procState;
16970        mPendingPssProcesses.add(proc);
16971    }
16972
16973    /**
16974     * Schedule PSS collection of all processes.
16975     */
16976    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16977        if (!always) {
16978            if (now < (mLastFullPssTime +
16979                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16980                return;
16981            }
16982        }
16983        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16984        mLastFullPssTime = now;
16985        mFullPssPending = true;
16986        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16987        mPendingPssProcesses.clear();
16988        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16989            ProcessRecord app = mLruProcesses.get(i);
16990            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16991                app.pssProcState = app.setProcState;
16992                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16993                        isSleeping(), now);
16994                mPendingPssProcesses.add(app);
16995            }
16996        }
16997        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16998    }
16999
17000    /**
17001     * Ask a given process to GC right now.
17002     */
17003    final void performAppGcLocked(ProcessRecord app) {
17004        try {
17005            app.lastRequestedGc = SystemClock.uptimeMillis();
17006            if (app.thread != null) {
17007                if (app.reportLowMemory) {
17008                    app.reportLowMemory = false;
17009                    app.thread.scheduleLowMemory();
17010                } else {
17011                    app.thread.processInBackground();
17012                }
17013            }
17014        } catch (Exception e) {
17015            // whatever.
17016        }
17017    }
17018
17019    /**
17020     * Returns true if things are idle enough to perform GCs.
17021     */
17022    private final boolean canGcNowLocked() {
17023        boolean processingBroadcasts = false;
17024        for (BroadcastQueue q : mBroadcastQueues) {
17025            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17026                processingBroadcasts = true;
17027            }
17028        }
17029        return !processingBroadcasts
17030                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17031    }
17032
17033    /**
17034     * Perform GCs on all processes that are waiting for it, but only
17035     * if things are idle.
17036     */
17037    final void performAppGcsLocked() {
17038        final int N = mProcessesToGc.size();
17039        if (N <= 0) {
17040            return;
17041        }
17042        if (canGcNowLocked()) {
17043            while (mProcessesToGc.size() > 0) {
17044                ProcessRecord proc = mProcessesToGc.remove(0);
17045                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17046                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17047                            <= SystemClock.uptimeMillis()) {
17048                        // To avoid spamming the system, we will GC processes one
17049                        // at a time, waiting a few seconds between each.
17050                        performAppGcLocked(proc);
17051                        scheduleAppGcsLocked();
17052                        return;
17053                    } else {
17054                        // It hasn't been long enough since we last GCed this
17055                        // process...  put it in the list to wait for its time.
17056                        addProcessToGcListLocked(proc);
17057                        break;
17058                    }
17059                }
17060            }
17061
17062            scheduleAppGcsLocked();
17063        }
17064    }
17065
17066    /**
17067     * If all looks good, perform GCs on all processes waiting for them.
17068     */
17069    final void performAppGcsIfAppropriateLocked() {
17070        if (canGcNowLocked()) {
17071            performAppGcsLocked();
17072            return;
17073        }
17074        // Still not idle, wait some more.
17075        scheduleAppGcsLocked();
17076    }
17077
17078    /**
17079     * Schedule the execution of all pending app GCs.
17080     */
17081    final void scheduleAppGcsLocked() {
17082        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17083
17084        if (mProcessesToGc.size() > 0) {
17085            // Schedule a GC for the time to the next process.
17086            ProcessRecord proc = mProcessesToGc.get(0);
17087            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17088
17089            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17090            long now = SystemClock.uptimeMillis();
17091            if (when < (now+GC_TIMEOUT)) {
17092                when = now + GC_TIMEOUT;
17093            }
17094            mHandler.sendMessageAtTime(msg, when);
17095        }
17096    }
17097
17098    /**
17099     * Add a process to the array of processes waiting to be GCed.  Keeps the
17100     * list in sorted order by the last GC time.  The process can't already be
17101     * on the list.
17102     */
17103    final void addProcessToGcListLocked(ProcessRecord proc) {
17104        boolean added = false;
17105        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17106            if (mProcessesToGc.get(i).lastRequestedGc <
17107                    proc.lastRequestedGc) {
17108                added = true;
17109                mProcessesToGc.add(i+1, proc);
17110                break;
17111            }
17112        }
17113        if (!added) {
17114            mProcessesToGc.add(0, proc);
17115        }
17116    }
17117
17118    /**
17119     * Set up to ask a process to GC itself.  This will either do it
17120     * immediately, or put it on the list of processes to gc the next
17121     * time things are idle.
17122     */
17123    final void scheduleAppGcLocked(ProcessRecord app) {
17124        long now = SystemClock.uptimeMillis();
17125        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17126            return;
17127        }
17128        if (!mProcessesToGc.contains(app)) {
17129            addProcessToGcListLocked(app);
17130            scheduleAppGcsLocked();
17131        }
17132    }
17133
17134    final void checkExcessivePowerUsageLocked(boolean doKills) {
17135        updateCpuStatsNow();
17136
17137        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17138        boolean doWakeKills = doKills;
17139        boolean doCpuKills = doKills;
17140        if (mLastPowerCheckRealtime == 0) {
17141            doWakeKills = false;
17142        }
17143        if (mLastPowerCheckUptime == 0) {
17144            doCpuKills = false;
17145        }
17146        if (stats.isScreenOn()) {
17147            doWakeKills = false;
17148        }
17149        final long curRealtime = SystemClock.elapsedRealtime();
17150        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17151        final long curUptime = SystemClock.uptimeMillis();
17152        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17153        mLastPowerCheckRealtime = curRealtime;
17154        mLastPowerCheckUptime = curUptime;
17155        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17156            doWakeKills = false;
17157        }
17158        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17159            doCpuKills = false;
17160        }
17161        int i = mLruProcesses.size();
17162        while (i > 0) {
17163            i--;
17164            ProcessRecord app = mLruProcesses.get(i);
17165            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17166                long wtime;
17167                synchronized (stats) {
17168                    wtime = stats.getProcessWakeTime(app.info.uid,
17169                            app.pid, curRealtime);
17170                }
17171                long wtimeUsed = wtime - app.lastWakeTime;
17172                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17173                if (DEBUG_POWER) {
17174                    StringBuilder sb = new StringBuilder(128);
17175                    sb.append("Wake for ");
17176                    app.toShortString(sb);
17177                    sb.append(": over ");
17178                    TimeUtils.formatDuration(realtimeSince, sb);
17179                    sb.append(" used ");
17180                    TimeUtils.formatDuration(wtimeUsed, sb);
17181                    sb.append(" (");
17182                    sb.append((wtimeUsed*100)/realtimeSince);
17183                    sb.append("%)");
17184                    Slog.i(TAG, sb.toString());
17185                    sb.setLength(0);
17186                    sb.append("CPU for ");
17187                    app.toShortString(sb);
17188                    sb.append(": over ");
17189                    TimeUtils.formatDuration(uptimeSince, sb);
17190                    sb.append(" used ");
17191                    TimeUtils.formatDuration(cputimeUsed, sb);
17192                    sb.append(" (");
17193                    sb.append((cputimeUsed*100)/uptimeSince);
17194                    sb.append("%)");
17195                    Slog.i(TAG, sb.toString());
17196                }
17197                // If a process has held a wake lock for more
17198                // than 50% of the time during this period,
17199                // that sounds bad.  Kill!
17200                if (doWakeKills && realtimeSince > 0
17201                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17202                    synchronized (stats) {
17203                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17204                                realtimeSince, wtimeUsed);
17205                    }
17206                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17207                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17208                } else if (doCpuKills && uptimeSince > 0
17209                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17210                    synchronized (stats) {
17211                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17212                                uptimeSince, cputimeUsed);
17213                    }
17214                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17215                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17216                } else {
17217                    app.lastWakeTime = wtime;
17218                    app.lastCpuTime = app.curCpuTime;
17219                }
17220            }
17221        }
17222    }
17223
17224    private final boolean applyOomAdjLocked(ProcessRecord app,
17225            ProcessRecord TOP_APP, boolean doingAll, long now) {
17226        boolean success = true;
17227
17228        if (app.curRawAdj != app.setRawAdj) {
17229            app.setRawAdj = app.curRawAdj;
17230        }
17231
17232        int changes = 0;
17233
17234        if (app.curAdj != app.setAdj) {
17235            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17236            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17237                TAG, "Set " + app.pid + " " + app.processName +
17238                " adj " + app.curAdj + ": " + app.adjType);
17239            app.setAdj = app.curAdj;
17240        }
17241
17242        if (app.setSchedGroup != app.curSchedGroup) {
17243            app.setSchedGroup = app.curSchedGroup;
17244            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17245                    "Setting process group of " + app.processName
17246                    + " to " + app.curSchedGroup);
17247            if (app.waitingToKill != null &&
17248                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17249                app.kill(app.waitingToKill, true);
17250                success = false;
17251            } else {
17252                if (true) {
17253                    long oldId = Binder.clearCallingIdentity();
17254                    try {
17255                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17256                    } catch (Exception e) {
17257                        Slog.w(TAG, "Failed setting process group of " + app.pid
17258                                + " to " + app.curSchedGroup);
17259                        e.printStackTrace();
17260                    } finally {
17261                        Binder.restoreCallingIdentity(oldId);
17262                    }
17263                } else {
17264                    if (app.thread != null) {
17265                        try {
17266                            app.thread.setSchedulingGroup(app.curSchedGroup);
17267                        } catch (RemoteException e) {
17268                        }
17269                    }
17270                }
17271                Process.setSwappiness(app.pid,
17272                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17273            }
17274        }
17275        if (app.repForegroundActivities != app.foregroundActivities) {
17276            app.repForegroundActivities = app.foregroundActivities;
17277            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17278        }
17279        if (app.repProcState != app.curProcState) {
17280            app.repProcState = app.curProcState;
17281            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17282            if (app.thread != null) {
17283                try {
17284                    if (false) {
17285                        //RuntimeException h = new RuntimeException("here");
17286                        Slog.i(TAG, "Sending new process state " + app.repProcState
17287                                + " to " + app /*, h*/);
17288                    }
17289                    app.thread.setProcessState(app.repProcState);
17290                } catch (RemoteException e) {
17291                }
17292            }
17293        }
17294        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17295                app.setProcState)) {
17296            app.lastStateTime = now;
17297            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17298                    isSleeping(), now);
17299            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17300                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17301                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17302                    + (app.nextPssTime-now) + ": " + app);
17303        } else {
17304            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17305                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17306                requestPssLocked(app, app.setProcState);
17307                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17308                        isSleeping(), now);
17309            } else if (false && DEBUG_PSS) {
17310                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17311            }
17312        }
17313        if (app.setProcState != app.curProcState) {
17314            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17315                    "Proc state change of " + app.processName
17316                    + " to " + app.curProcState);
17317            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17318            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17319            if (setImportant && !curImportant) {
17320                // This app is no longer something we consider important enough to allow to
17321                // use arbitrary amounts of battery power.  Note
17322                // its current wake lock time to later know to kill it if
17323                // it is not behaving well.
17324                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17325                synchronized (stats) {
17326                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17327                            app.pid, SystemClock.elapsedRealtime());
17328                }
17329                app.lastCpuTime = app.curCpuTime;
17330
17331            }
17332            app.setProcState = app.curProcState;
17333            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17334                app.notCachedSinceIdle = false;
17335            }
17336            if (!doingAll) {
17337                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17338            } else {
17339                app.procStateChanged = true;
17340            }
17341        }
17342
17343        if (changes != 0) {
17344            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17345            int i = mPendingProcessChanges.size()-1;
17346            ProcessChangeItem item = null;
17347            while (i >= 0) {
17348                item = mPendingProcessChanges.get(i);
17349                if (item.pid == app.pid) {
17350                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17351                    break;
17352                }
17353                i--;
17354            }
17355            if (i < 0) {
17356                // No existing item in pending changes; need a new one.
17357                final int NA = mAvailProcessChanges.size();
17358                if (NA > 0) {
17359                    item = mAvailProcessChanges.remove(NA-1);
17360                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17361                } else {
17362                    item = new ProcessChangeItem();
17363                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17364                }
17365                item.changes = 0;
17366                item.pid = app.pid;
17367                item.uid = app.info.uid;
17368                if (mPendingProcessChanges.size() == 0) {
17369                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17370                            "*** Enqueueing dispatch processes changed!");
17371                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17372                }
17373                mPendingProcessChanges.add(item);
17374            }
17375            item.changes |= changes;
17376            item.processState = app.repProcState;
17377            item.foregroundActivities = app.repForegroundActivities;
17378            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17379                    + Integer.toHexString(System.identityHashCode(item))
17380                    + " " + app.toShortString() + ": changes=" + item.changes
17381                    + " procState=" + item.processState
17382                    + " foreground=" + item.foregroundActivities
17383                    + " type=" + app.adjType + " source=" + app.adjSource
17384                    + " target=" + app.adjTarget);
17385        }
17386
17387        return success;
17388    }
17389
17390    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17391        if (proc.thread != null) {
17392            if (proc.baseProcessTracker != null) {
17393                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17394            }
17395            if (proc.repProcState >= 0) {
17396                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17397                        proc.repProcState);
17398            }
17399        }
17400    }
17401
17402    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17403            ProcessRecord TOP_APP, boolean doingAll, long now) {
17404        if (app.thread == null) {
17405            return false;
17406        }
17407
17408        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17409
17410        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17411    }
17412
17413    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17414            boolean oomAdj) {
17415        if (isForeground != proc.foregroundServices) {
17416            proc.foregroundServices = isForeground;
17417            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17418                    proc.info.uid);
17419            if (isForeground) {
17420                if (curProcs == null) {
17421                    curProcs = new ArrayList<ProcessRecord>();
17422                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17423                }
17424                if (!curProcs.contains(proc)) {
17425                    curProcs.add(proc);
17426                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17427                            proc.info.packageName, proc.info.uid);
17428                }
17429            } else {
17430                if (curProcs != null) {
17431                    if (curProcs.remove(proc)) {
17432                        mBatteryStatsService.noteEvent(
17433                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17434                                proc.info.packageName, proc.info.uid);
17435                        if (curProcs.size() <= 0) {
17436                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17437                        }
17438                    }
17439                }
17440            }
17441            if (oomAdj) {
17442                updateOomAdjLocked();
17443            }
17444        }
17445    }
17446
17447    private final ActivityRecord resumedAppLocked() {
17448        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17449        String pkg;
17450        int uid;
17451        if (act != null) {
17452            pkg = act.packageName;
17453            uid = act.info.applicationInfo.uid;
17454        } else {
17455            pkg = null;
17456            uid = -1;
17457        }
17458        // Has the UID or resumed package name changed?
17459        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17460                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17461            if (mCurResumedPackage != null) {
17462                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17463                        mCurResumedPackage, mCurResumedUid);
17464            }
17465            mCurResumedPackage = pkg;
17466            mCurResumedUid = uid;
17467            if (mCurResumedPackage != null) {
17468                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17469                        mCurResumedPackage, mCurResumedUid);
17470            }
17471        }
17472        return act;
17473    }
17474
17475    final boolean updateOomAdjLocked(ProcessRecord app) {
17476        final ActivityRecord TOP_ACT = resumedAppLocked();
17477        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17478        final boolean wasCached = app.cached;
17479
17480        mAdjSeq++;
17481
17482        // This is the desired cached adjusment we want to tell it to use.
17483        // If our app is currently cached, we know it, and that is it.  Otherwise,
17484        // we don't know it yet, and it needs to now be cached we will then
17485        // need to do a complete oom adj.
17486        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17487                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17488        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17489                SystemClock.uptimeMillis());
17490        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17491            // Changed to/from cached state, so apps after it in the LRU
17492            // list may also be changed.
17493            updateOomAdjLocked();
17494        }
17495        return success;
17496    }
17497
17498    final void updateOomAdjLocked() {
17499        final ActivityRecord TOP_ACT = resumedAppLocked();
17500        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17501        final long now = SystemClock.uptimeMillis();
17502        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17503        final int N = mLruProcesses.size();
17504
17505        if (false) {
17506            RuntimeException e = new RuntimeException();
17507            e.fillInStackTrace();
17508            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17509        }
17510
17511        mAdjSeq++;
17512        mNewNumServiceProcs = 0;
17513        mNewNumAServiceProcs = 0;
17514
17515        final int emptyProcessLimit;
17516        final int cachedProcessLimit;
17517        if (mProcessLimit <= 0) {
17518            emptyProcessLimit = cachedProcessLimit = 0;
17519        } else if (mProcessLimit == 1) {
17520            emptyProcessLimit = 1;
17521            cachedProcessLimit = 0;
17522        } else {
17523            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17524            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17525        }
17526
17527        // Let's determine how many processes we have running vs.
17528        // how many slots we have for background processes; we may want
17529        // to put multiple processes in a slot of there are enough of
17530        // them.
17531        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17532                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17533        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17534        if (numEmptyProcs > cachedProcessLimit) {
17535            // If there are more empty processes than our limit on cached
17536            // processes, then use the cached process limit for the factor.
17537            // This ensures that the really old empty processes get pushed
17538            // down to the bottom, so if we are running low on memory we will
17539            // have a better chance at keeping around more cached processes
17540            // instead of a gazillion empty processes.
17541            numEmptyProcs = cachedProcessLimit;
17542        }
17543        int emptyFactor = numEmptyProcs/numSlots;
17544        if (emptyFactor < 1) emptyFactor = 1;
17545        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17546        if (cachedFactor < 1) cachedFactor = 1;
17547        int stepCached = 0;
17548        int stepEmpty = 0;
17549        int numCached = 0;
17550        int numEmpty = 0;
17551        int numTrimming = 0;
17552
17553        mNumNonCachedProcs = 0;
17554        mNumCachedHiddenProcs = 0;
17555
17556        // First update the OOM adjustment for each of the
17557        // application processes based on their current state.
17558        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17559        int nextCachedAdj = curCachedAdj+1;
17560        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17561        int nextEmptyAdj = curEmptyAdj+2;
17562        for (int i=N-1; i>=0; i--) {
17563            ProcessRecord app = mLruProcesses.get(i);
17564            if (!app.killedByAm && app.thread != null) {
17565                app.procStateChanged = false;
17566                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17567
17568                // If we haven't yet assigned the final cached adj
17569                // to the process, do that now.
17570                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17571                    switch (app.curProcState) {
17572                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17573                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17574                            // This process is a cached process holding activities...
17575                            // assign it the next cached value for that type, and then
17576                            // step that cached level.
17577                            app.curRawAdj = curCachedAdj;
17578                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17579                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17580                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17581                                    + ")");
17582                            if (curCachedAdj != nextCachedAdj) {
17583                                stepCached++;
17584                                if (stepCached >= cachedFactor) {
17585                                    stepCached = 0;
17586                                    curCachedAdj = nextCachedAdj;
17587                                    nextCachedAdj += 2;
17588                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17589                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17590                                    }
17591                                }
17592                            }
17593                            break;
17594                        default:
17595                            // For everything else, assign next empty cached process
17596                            // level and bump that up.  Note that this means that
17597                            // long-running services that have dropped down to the
17598                            // cached level will be treated as empty (since their process
17599                            // state is still as a service), which is what we want.
17600                            app.curRawAdj = curEmptyAdj;
17601                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17602                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17603                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17604                                    + ")");
17605                            if (curEmptyAdj != nextEmptyAdj) {
17606                                stepEmpty++;
17607                                if (stepEmpty >= emptyFactor) {
17608                                    stepEmpty = 0;
17609                                    curEmptyAdj = nextEmptyAdj;
17610                                    nextEmptyAdj += 2;
17611                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17612                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17613                                    }
17614                                }
17615                            }
17616                            break;
17617                    }
17618                }
17619
17620                applyOomAdjLocked(app, TOP_APP, true, now);
17621
17622                // Count the number of process types.
17623                switch (app.curProcState) {
17624                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17625                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17626                        mNumCachedHiddenProcs++;
17627                        numCached++;
17628                        if (numCached > cachedProcessLimit) {
17629                            app.kill("cached #" + numCached, true);
17630                        }
17631                        break;
17632                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17633                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17634                                && app.lastActivityTime < oldTime) {
17635                            app.kill("empty for "
17636                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17637                                    / 1000) + "s", true);
17638                        } else {
17639                            numEmpty++;
17640                            if (numEmpty > emptyProcessLimit) {
17641                                app.kill("empty #" + numEmpty, true);
17642                            }
17643                        }
17644                        break;
17645                    default:
17646                        mNumNonCachedProcs++;
17647                        break;
17648                }
17649
17650                if (app.isolated && app.services.size() <= 0) {
17651                    // If this is an isolated process, and there are no
17652                    // services running in it, then the process is no longer
17653                    // needed.  We agressively kill these because we can by
17654                    // definition not re-use the same process again, and it is
17655                    // good to avoid having whatever code was running in them
17656                    // left sitting around after no longer needed.
17657                    app.kill("isolated not needed", true);
17658                }
17659
17660                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17661                        && !app.killedByAm) {
17662                    numTrimming++;
17663                }
17664            }
17665        }
17666
17667        mNumServiceProcs = mNewNumServiceProcs;
17668
17669        // Now determine the memory trimming level of background processes.
17670        // Unfortunately we need to start at the back of the list to do this
17671        // properly.  We only do this if the number of background apps we
17672        // are managing to keep around is less than half the maximum we desire;
17673        // if we are keeping a good number around, we'll let them use whatever
17674        // memory they want.
17675        final int numCachedAndEmpty = numCached + numEmpty;
17676        int memFactor;
17677        if (numCached <= ProcessList.TRIM_CACHED_APPS
17678                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17679            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17680                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17681            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17682                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17683            } else {
17684                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17685            }
17686        } else {
17687            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17688        }
17689        // We always allow the memory level to go up (better).  We only allow it to go
17690        // down if we are in a state where that is allowed, *and* the total number of processes
17691        // has gone down since last time.
17692        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17693                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17694                + " last=" + mLastNumProcesses);
17695        if (memFactor > mLastMemoryLevel) {
17696            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17697                memFactor = mLastMemoryLevel;
17698                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17699            }
17700        }
17701        mLastMemoryLevel = memFactor;
17702        mLastNumProcesses = mLruProcesses.size();
17703        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17704        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17705        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17706            if (mLowRamStartTime == 0) {
17707                mLowRamStartTime = now;
17708            }
17709            int step = 0;
17710            int fgTrimLevel;
17711            switch (memFactor) {
17712                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17713                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17714                    break;
17715                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17716                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17717                    break;
17718                default:
17719                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17720                    break;
17721            }
17722            int factor = numTrimming/3;
17723            int minFactor = 2;
17724            if (mHomeProcess != null) minFactor++;
17725            if (mPreviousProcess != null) minFactor++;
17726            if (factor < minFactor) factor = minFactor;
17727            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17728            for (int i=N-1; i>=0; i--) {
17729                ProcessRecord app = mLruProcesses.get(i);
17730                if (allChanged || app.procStateChanged) {
17731                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17732                    app.procStateChanged = false;
17733                }
17734                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17735                        && !app.killedByAm) {
17736                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17737                        try {
17738                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17739                                    "Trimming memory of " + app.processName
17740                                    + " to " + curLevel);
17741                            app.thread.scheduleTrimMemory(curLevel);
17742                        } catch (RemoteException e) {
17743                        }
17744                        if (false) {
17745                            // For now we won't do this; our memory trimming seems
17746                            // to be good enough at this point that destroying
17747                            // activities causes more harm than good.
17748                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17749                                    && app != mHomeProcess && app != mPreviousProcess) {
17750                                // Need to do this on its own message because the stack may not
17751                                // be in a consistent state at this point.
17752                                // For these apps we will also finish their activities
17753                                // to help them free memory.
17754                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17755                            }
17756                        }
17757                    }
17758                    app.trimMemoryLevel = curLevel;
17759                    step++;
17760                    if (step >= factor) {
17761                        step = 0;
17762                        switch (curLevel) {
17763                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17764                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17765                                break;
17766                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17767                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17768                                break;
17769                        }
17770                    }
17771                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17772                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17773                            && app.thread != null) {
17774                        try {
17775                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17776                                    "Trimming memory of heavy-weight " + app.processName
17777                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17778                            app.thread.scheduleTrimMemory(
17779                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17780                        } catch (RemoteException e) {
17781                        }
17782                    }
17783                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17784                } else {
17785                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17786                            || app.systemNoUi) && app.pendingUiClean) {
17787                        // If this application is now in the background and it
17788                        // had done UI, then give it the special trim level to
17789                        // have it free UI resources.
17790                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17791                        if (app.trimMemoryLevel < level && app.thread != null) {
17792                            try {
17793                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17794                                        "Trimming memory of bg-ui " + app.processName
17795                                        + " to " + level);
17796                                app.thread.scheduleTrimMemory(level);
17797                            } catch (RemoteException e) {
17798                            }
17799                        }
17800                        app.pendingUiClean = false;
17801                    }
17802                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17803                        try {
17804                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17805                                    "Trimming memory of fg " + app.processName
17806                                    + " to " + fgTrimLevel);
17807                            app.thread.scheduleTrimMemory(fgTrimLevel);
17808                        } catch (RemoteException e) {
17809                        }
17810                    }
17811                    app.trimMemoryLevel = fgTrimLevel;
17812                }
17813            }
17814        } else {
17815            if (mLowRamStartTime != 0) {
17816                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17817                mLowRamStartTime = 0;
17818            }
17819            for (int i=N-1; i>=0; i--) {
17820                ProcessRecord app = mLruProcesses.get(i);
17821                if (allChanged || app.procStateChanged) {
17822                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17823                    app.procStateChanged = false;
17824                }
17825                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17826                        || app.systemNoUi) && app.pendingUiClean) {
17827                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17828                            && app.thread != null) {
17829                        try {
17830                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17831                                    "Trimming memory of ui hidden " + app.processName
17832                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17833                            app.thread.scheduleTrimMemory(
17834                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17835                        } catch (RemoteException e) {
17836                        }
17837                    }
17838                    app.pendingUiClean = false;
17839                }
17840                app.trimMemoryLevel = 0;
17841            }
17842        }
17843
17844        if (mAlwaysFinishActivities) {
17845            // Need to do this on its own message because the stack may not
17846            // be in a consistent state at this point.
17847            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17848        }
17849
17850        if (allChanged) {
17851            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17852        }
17853
17854        if (mProcessStats.shouldWriteNowLocked(now)) {
17855            mHandler.post(new Runnable() {
17856                @Override public void run() {
17857                    synchronized (ActivityManagerService.this) {
17858                        mProcessStats.writeStateAsyncLocked();
17859                    }
17860                }
17861            });
17862        }
17863
17864        if (DEBUG_OOM_ADJ) {
17865            if (false) {
17866                RuntimeException here = new RuntimeException("here");
17867                here.fillInStackTrace();
17868                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17869            } else {
17870                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17871            }
17872        }
17873    }
17874
17875    final void trimApplications() {
17876        synchronized (this) {
17877            int i;
17878
17879            // First remove any unused application processes whose package
17880            // has been removed.
17881            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17882                final ProcessRecord app = mRemovedProcesses.get(i);
17883                if (app.activities.size() == 0
17884                        && app.curReceiver == null && app.services.size() == 0) {
17885                    Slog.i(
17886                        TAG, "Exiting empty application process "
17887                        + app.processName + " ("
17888                        + (app.thread != null ? app.thread.asBinder() : null)
17889                        + ")\n");
17890                    if (app.pid > 0 && app.pid != MY_PID) {
17891                        app.kill("empty", false);
17892                    } else {
17893                        try {
17894                            app.thread.scheduleExit();
17895                        } catch (Exception e) {
17896                            // Ignore exceptions.
17897                        }
17898                    }
17899                    cleanUpApplicationRecordLocked(app, false, true, -1);
17900                    mRemovedProcesses.remove(i);
17901
17902                    if (app.persistent) {
17903                        addAppLocked(app.info, false, null /* ABI override */);
17904                    }
17905                }
17906            }
17907
17908            // Now update the oom adj for all processes.
17909            updateOomAdjLocked();
17910        }
17911    }
17912
17913    /** This method sends the specified signal to each of the persistent apps */
17914    public void signalPersistentProcesses(int sig) throws RemoteException {
17915        if (sig != Process.SIGNAL_USR1) {
17916            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17917        }
17918
17919        synchronized (this) {
17920            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17921                    != PackageManager.PERMISSION_GRANTED) {
17922                throw new SecurityException("Requires permission "
17923                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17924            }
17925
17926            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17927                ProcessRecord r = mLruProcesses.get(i);
17928                if (r.thread != null && r.persistent) {
17929                    Process.sendSignal(r.pid, sig);
17930                }
17931            }
17932        }
17933    }
17934
17935    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17936        if (proc == null || proc == mProfileProc) {
17937            proc = mProfileProc;
17938            profileType = mProfileType;
17939            clearProfilerLocked();
17940        }
17941        if (proc == null) {
17942            return;
17943        }
17944        try {
17945            proc.thread.profilerControl(false, null, profileType);
17946        } catch (RemoteException e) {
17947            throw new IllegalStateException("Process disappeared");
17948        }
17949    }
17950
17951    private void clearProfilerLocked() {
17952        if (mProfileFd != null) {
17953            try {
17954                mProfileFd.close();
17955            } catch (IOException e) {
17956            }
17957        }
17958        mProfileApp = null;
17959        mProfileProc = null;
17960        mProfileFile = null;
17961        mProfileType = 0;
17962        mAutoStopProfiler = false;
17963        mSamplingInterval = 0;
17964    }
17965
17966    public boolean profileControl(String process, int userId, boolean start,
17967            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17968
17969        try {
17970            synchronized (this) {
17971                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17972                // its own permission.
17973                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17974                        != PackageManager.PERMISSION_GRANTED) {
17975                    throw new SecurityException("Requires permission "
17976                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17977                }
17978
17979                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17980                    throw new IllegalArgumentException("null profile info or fd");
17981                }
17982
17983                ProcessRecord proc = null;
17984                if (process != null) {
17985                    proc = findProcessLocked(process, userId, "profileControl");
17986                }
17987
17988                if (start && (proc == null || proc.thread == null)) {
17989                    throw new IllegalArgumentException("Unknown process: " + process);
17990                }
17991
17992                if (start) {
17993                    stopProfilerLocked(null, 0);
17994                    setProfileApp(proc.info, proc.processName, profilerInfo);
17995                    mProfileProc = proc;
17996                    mProfileType = profileType;
17997                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17998                    try {
17999                        fd = fd.dup();
18000                    } catch (IOException e) {
18001                        fd = null;
18002                    }
18003                    profilerInfo.profileFd = fd;
18004                    proc.thread.profilerControl(start, profilerInfo, profileType);
18005                    fd = null;
18006                    mProfileFd = null;
18007                } else {
18008                    stopProfilerLocked(proc, profileType);
18009                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18010                        try {
18011                            profilerInfo.profileFd.close();
18012                        } catch (IOException e) {
18013                        }
18014                    }
18015                }
18016
18017                return true;
18018            }
18019        } catch (RemoteException e) {
18020            throw new IllegalStateException("Process disappeared");
18021        } finally {
18022            if (profilerInfo != null && profilerInfo.profileFd != null) {
18023                try {
18024                    profilerInfo.profileFd.close();
18025                } catch (IOException e) {
18026                }
18027            }
18028        }
18029    }
18030
18031    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18032        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18033                userId, true, ALLOW_FULL_ONLY, callName, null);
18034        ProcessRecord proc = null;
18035        try {
18036            int pid = Integer.parseInt(process);
18037            synchronized (mPidsSelfLocked) {
18038                proc = mPidsSelfLocked.get(pid);
18039            }
18040        } catch (NumberFormatException e) {
18041        }
18042
18043        if (proc == null) {
18044            ArrayMap<String, SparseArray<ProcessRecord>> all
18045                    = mProcessNames.getMap();
18046            SparseArray<ProcessRecord> procs = all.get(process);
18047            if (procs != null && procs.size() > 0) {
18048                proc = procs.valueAt(0);
18049                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18050                    for (int i=1; i<procs.size(); i++) {
18051                        ProcessRecord thisProc = procs.valueAt(i);
18052                        if (thisProc.userId == userId) {
18053                            proc = thisProc;
18054                            break;
18055                        }
18056                    }
18057                }
18058            }
18059        }
18060
18061        return proc;
18062    }
18063
18064    public boolean dumpHeap(String process, int userId, boolean managed,
18065            String path, ParcelFileDescriptor fd) throws RemoteException {
18066
18067        try {
18068            synchronized (this) {
18069                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18070                // its own permission (same as profileControl).
18071                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18072                        != PackageManager.PERMISSION_GRANTED) {
18073                    throw new SecurityException("Requires permission "
18074                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18075                }
18076
18077                if (fd == null) {
18078                    throw new IllegalArgumentException("null fd");
18079                }
18080
18081                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18082                if (proc == null || proc.thread == null) {
18083                    throw new IllegalArgumentException("Unknown process: " + process);
18084                }
18085
18086                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18087                if (!isDebuggable) {
18088                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18089                        throw new SecurityException("Process not debuggable: " + proc);
18090                    }
18091                }
18092
18093                proc.thread.dumpHeap(managed, path, fd);
18094                fd = null;
18095                return true;
18096            }
18097        } catch (RemoteException e) {
18098            throw new IllegalStateException("Process disappeared");
18099        } finally {
18100            if (fd != null) {
18101                try {
18102                    fd.close();
18103                } catch (IOException e) {
18104                }
18105            }
18106        }
18107    }
18108
18109    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18110    public void monitor() {
18111        synchronized (this) { }
18112    }
18113
18114    void onCoreSettingsChange(Bundle settings) {
18115        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18116            ProcessRecord processRecord = mLruProcesses.get(i);
18117            try {
18118                if (processRecord.thread != null) {
18119                    processRecord.thread.setCoreSettings(settings);
18120                }
18121            } catch (RemoteException re) {
18122                /* ignore */
18123            }
18124        }
18125    }
18126
18127    // Multi-user methods
18128
18129    /**
18130     * Start user, if its not already running, but don't bring it to foreground.
18131     */
18132    @Override
18133    public boolean startUserInBackground(final int userId) {
18134        return startUser(userId, /* foreground */ false);
18135    }
18136
18137    /**
18138     * Start user, if its not already running, and bring it to foreground.
18139     */
18140    boolean startUserInForeground(final int userId, Dialog dlg) {
18141        boolean result = startUser(userId, /* foreground */ true);
18142        dlg.dismiss();
18143        return result;
18144    }
18145
18146    /**
18147     * Refreshes the list of users related to the current user when either a
18148     * user switch happens or when a new related user is started in the
18149     * background.
18150     */
18151    private void updateCurrentProfileIdsLocked() {
18152        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18153                mCurrentUserId, false /* enabledOnly */);
18154        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18155        for (int i = 0; i < currentProfileIds.length; i++) {
18156            currentProfileIds[i] = profiles.get(i).id;
18157        }
18158        mCurrentProfileIds = currentProfileIds;
18159
18160        synchronized (mUserProfileGroupIdsSelfLocked) {
18161            mUserProfileGroupIdsSelfLocked.clear();
18162            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18163            for (int i = 0; i < users.size(); i++) {
18164                UserInfo user = users.get(i);
18165                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18166                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18167                }
18168            }
18169        }
18170    }
18171
18172    private Set getProfileIdsLocked(int userId) {
18173        Set userIds = new HashSet<Integer>();
18174        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18175                userId, false /* enabledOnly */);
18176        for (UserInfo user : profiles) {
18177            userIds.add(Integer.valueOf(user.id));
18178        }
18179        return userIds;
18180    }
18181
18182    @Override
18183    public boolean switchUser(final int userId) {
18184        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18185        String userName;
18186        synchronized (this) {
18187            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18188            if (userInfo == null) {
18189                Slog.w(TAG, "No user info for user #" + userId);
18190                return false;
18191            }
18192            if (userInfo.isManagedProfile()) {
18193                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18194                return false;
18195            }
18196            userName = userInfo.name;
18197            mTargetUserId = userId;
18198        }
18199        mHandler.removeMessages(START_USER_SWITCH_MSG);
18200        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18201        return true;
18202    }
18203
18204    private void showUserSwitchDialog(int userId, String userName) {
18205        // The dialog will show and then initiate the user switch by calling startUserInForeground
18206        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18207                true /* above system */);
18208        d.show();
18209    }
18210
18211    private boolean startUser(final int userId, final boolean foreground) {
18212        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18213                != PackageManager.PERMISSION_GRANTED) {
18214            String msg = "Permission Denial: switchUser() from pid="
18215                    + Binder.getCallingPid()
18216                    + ", uid=" + Binder.getCallingUid()
18217                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18218            Slog.w(TAG, msg);
18219            throw new SecurityException(msg);
18220        }
18221
18222        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18223
18224        final long ident = Binder.clearCallingIdentity();
18225        try {
18226            synchronized (this) {
18227                final int oldUserId = mCurrentUserId;
18228                if (oldUserId == userId) {
18229                    return true;
18230                }
18231
18232                mStackSupervisor.setLockTaskModeLocked(null, false);
18233
18234                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18235                if (userInfo == null) {
18236                    Slog.w(TAG, "No user info for user #" + userId);
18237                    return false;
18238                }
18239                if (foreground && userInfo.isManagedProfile()) {
18240                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18241                    return false;
18242                }
18243
18244                if (foreground) {
18245                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18246                            R.anim.screen_user_enter);
18247                }
18248
18249                boolean needStart = false;
18250
18251                // If the user we are switching to is not currently started, then
18252                // we need to start it now.
18253                if (mStartedUsers.get(userId) == null) {
18254                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18255                    updateStartedUserArrayLocked();
18256                    needStart = true;
18257                }
18258
18259                final Integer userIdInt = Integer.valueOf(userId);
18260                mUserLru.remove(userIdInt);
18261                mUserLru.add(userIdInt);
18262
18263                if (foreground) {
18264                    mCurrentUserId = userId;
18265                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18266                    updateCurrentProfileIdsLocked();
18267                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18268                    // Once the internal notion of the active user has switched, we lock the device
18269                    // with the option to show the user switcher on the keyguard.
18270                    mWindowManager.lockNow(null);
18271                } else {
18272                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18273                    updateCurrentProfileIdsLocked();
18274                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18275                    mUserLru.remove(currentUserIdInt);
18276                    mUserLru.add(currentUserIdInt);
18277                }
18278
18279                final UserStartedState uss = mStartedUsers.get(userId);
18280
18281                // Make sure user is in the started state.  If it is currently
18282                // stopping, we need to knock that off.
18283                if (uss.mState == UserStartedState.STATE_STOPPING) {
18284                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18285                    // so we can just fairly silently bring the user back from
18286                    // the almost-dead.
18287                    uss.mState = UserStartedState.STATE_RUNNING;
18288                    updateStartedUserArrayLocked();
18289                    needStart = true;
18290                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18291                    // This means ACTION_SHUTDOWN has been sent, so we will
18292                    // need to treat this as a new boot of the user.
18293                    uss.mState = UserStartedState.STATE_BOOTING;
18294                    updateStartedUserArrayLocked();
18295                    needStart = true;
18296                }
18297
18298                if (uss.mState == UserStartedState.STATE_BOOTING) {
18299                    // Booting up a new user, need to tell system services about it.
18300                    // Note that this is on the same handler as scheduling of broadcasts,
18301                    // which is important because it needs to go first.
18302                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18303                }
18304
18305                if (foreground) {
18306                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18307                            oldUserId));
18308                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18309                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18310                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18311                            oldUserId, userId, uss));
18312                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18313                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18314                }
18315
18316                if (needStart) {
18317                    // Send USER_STARTED broadcast
18318                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18319                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18320                            | Intent.FLAG_RECEIVER_FOREGROUND);
18321                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18322                    broadcastIntentLocked(null, null, intent,
18323                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18324                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18325                }
18326
18327                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18328                    if (userId != UserHandle.USER_OWNER) {
18329                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18330                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18331                        broadcastIntentLocked(null, null, intent, null,
18332                                new IIntentReceiver.Stub() {
18333                                    public void performReceive(Intent intent, int resultCode,
18334                                            String data, Bundle extras, boolean ordered,
18335                                            boolean sticky, int sendingUser) {
18336                                        onUserInitialized(uss, foreground, oldUserId, userId);
18337                                    }
18338                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18339                                true, false, MY_PID, Process.SYSTEM_UID,
18340                                userId);
18341                        uss.initializing = true;
18342                    } else {
18343                        getUserManagerLocked().makeInitialized(userInfo.id);
18344                    }
18345                }
18346
18347                if (foreground) {
18348                    if (!uss.initializing) {
18349                        moveUserToForeground(uss, oldUserId, userId);
18350                    }
18351                } else {
18352                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18353                }
18354
18355                if (needStart) {
18356                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18357                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18358                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18359                    broadcastIntentLocked(null, null, intent,
18360                            null, new IIntentReceiver.Stub() {
18361                                @Override
18362                                public void performReceive(Intent intent, int resultCode, String data,
18363                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18364                                        throws RemoteException {
18365                                }
18366                            }, 0, null, null,
18367                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18368                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18369                }
18370            }
18371        } finally {
18372            Binder.restoreCallingIdentity(ident);
18373        }
18374
18375        return true;
18376    }
18377
18378    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18379        long ident = Binder.clearCallingIdentity();
18380        try {
18381            Intent intent;
18382            if (oldUserId >= 0) {
18383                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18384                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18385                int count = profiles.size();
18386                for (int i = 0; i < count; i++) {
18387                    int profileUserId = profiles.get(i).id;
18388                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18389                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18390                            | Intent.FLAG_RECEIVER_FOREGROUND);
18391                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18392                    broadcastIntentLocked(null, null, intent,
18393                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18394                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18395                }
18396            }
18397            if (newUserId >= 0) {
18398                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18399                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18400                int count = profiles.size();
18401                for (int i = 0; i < count; i++) {
18402                    int profileUserId = profiles.get(i).id;
18403                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18404                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18405                            | Intent.FLAG_RECEIVER_FOREGROUND);
18406                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18407                    broadcastIntentLocked(null, null, intent,
18408                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18409                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18410                }
18411                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18412                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18413                        | Intent.FLAG_RECEIVER_FOREGROUND);
18414                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18415                broadcastIntentLocked(null, null, intent,
18416                        null, null, 0, null, null,
18417                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18418                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18419            }
18420        } finally {
18421            Binder.restoreCallingIdentity(ident);
18422        }
18423    }
18424
18425    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18426            final int newUserId) {
18427        final int N = mUserSwitchObservers.beginBroadcast();
18428        if (N > 0) {
18429            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18430                int mCount = 0;
18431                @Override
18432                public void sendResult(Bundle data) throws RemoteException {
18433                    synchronized (ActivityManagerService.this) {
18434                        if (mCurUserSwitchCallback == this) {
18435                            mCount++;
18436                            if (mCount == N) {
18437                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18438                            }
18439                        }
18440                    }
18441                }
18442            };
18443            synchronized (this) {
18444                uss.switching = true;
18445                mCurUserSwitchCallback = callback;
18446            }
18447            for (int i=0; i<N; i++) {
18448                try {
18449                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18450                            newUserId, callback);
18451                } catch (RemoteException e) {
18452                }
18453            }
18454        } else {
18455            synchronized (this) {
18456                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18457            }
18458        }
18459        mUserSwitchObservers.finishBroadcast();
18460    }
18461
18462    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18463        synchronized (this) {
18464            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18465            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18466        }
18467    }
18468
18469    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18470        mCurUserSwitchCallback = null;
18471        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18472        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18473                oldUserId, newUserId, uss));
18474    }
18475
18476    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18477        synchronized (this) {
18478            if (foreground) {
18479                moveUserToForeground(uss, oldUserId, newUserId);
18480            }
18481        }
18482
18483        completeSwitchAndInitalize(uss, newUserId, true, false);
18484    }
18485
18486    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18487        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18488        if (homeInFront) {
18489            startHomeActivityLocked(newUserId);
18490        } else {
18491            mStackSupervisor.resumeTopActivitiesLocked();
18492        }
18493        EventLogTags.writeAmSwitchUser(newUserId);
18494        getUserManagerLocked().userForeground(newUserId);
18495        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18496    }
18497
18498    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18499        completeSwitchAndInitalize(uss, newUserId, false, true);
18500    }
18501
18502    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18503            boolean clearInitializing, boolean clearSwitching) {
18504        boolean unfrozen = false;
18505        synchronized (this) {
18506            if (clearInitializing) {
18507                uss.initializing = false;
18508                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18509            }
18510            if (clearSwitching) {
18511                uss.switching = false;
18512            }
18513            if (!uss.switching && !uss.initializing) {
18514                mWindowManager.stopFreezingScreen();
18515                unfrozen = true;
18516            }
18517        }
18518        if (unfrozen) {
18519            final int N = mUserSwitchObservers.beginBroadcast();
18520            for (int i=0; i<N; i++) {
18521                try {
18522                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18523                } catch (RemoteException e) {
18524                }
18525            }
18526            mUserSwitchObservers.finishBroadcast();
18527        }
18528    }
18529
18530    void scheduleStartProfilesLocked() {
18531        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18532            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18533                    DateUtils.SECOND_IN_MILLIS);
18534        }
18535    }
18536
18537    void startProfilesLocked() {
18538        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18539        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18540                mCurrentUserId, false /* enabledOnly */);
18541        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18542        for (UserInfo user : profiles) {
18543            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18544                    && user.id != mCurrentUserId) {
18545                toStart.add(user);
18546            }
18547        }
18548        final int n = toStart.size();
18549        int i = 0;
18550        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18551            startUserInBackground(toStart.get(i).id);
18552        }
18553        if (i < n) {
18554            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18555        }
18556    }
18557
18558    void finishUserBoot(UserStartedState uss) {
18559        synchronized (this) {
18560            if (uss.mState == UserStartedState.STATE_BOOTING
18561                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18562                uss.mState = UserStartedState.STATE_RUNNING;
18563                final int userId = uss.mHandle.getIdentifier();
18564                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18565                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18566                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18567                broadcastIntentLocked(null, null, intent,
18568                        null, null, 0, null, null,
18569                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18570                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18571            }
18572        }
18573    }
18574
18575    void finishUserSwitch(UserStartedState uss) {
18576        synchronized (this) {
18577            finishUserBoot(uss);
18578
18579            startProfilesLocked();
18580
18581            int num = mUserLru.size();
18582            int i = 0;
18583            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18584                Integer oldUserId = mUserLru.get(i);
18585                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18586                if (oldUss == null) {
18587                    // Shouldn't happen, but be sane if it does.
18588                    mUserLru.remove(i);
18589                    num--;
18590                    continue;
18591                }
18592                if (oldUss.mState == UserStartedState.STATE_STOPPING
18593                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18594                    // This user is already stopping, doesn't count.
18595                    num--;
18596                    i++;
18597                    continue;
18598                }
18599                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18600                    // Owner and current can't be stopped, but count as running.
18601                    i++;
18602                    continue;
18603                }
18604                // This is a user to be stopped.
18605                stopUserLocked(oldUserId, null);
18606                num--;
18607                i++;
18608            }
18609        }
18610    }
18611
18612    @Override
18613    public int stopUser(final int userId, final IStopUserCallback callback) {
18614        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18615                != PackageManager.PERMISSION_GRANTED) {
18616            String msg = "Permission Denial: switchUser() from pid="
18617                    + Binder.getCallingPid()
18618                    + ", uid=" + Binder.getCallingUid()
18619                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18620            Slog.w(TAG, msg);
18621            throw new SecurityException(msg);
18622        }
18623        if (userId <= 0) {
18624            throw new IllegalArgumentException("Can't stop primary user " + userId);
18625        }
18626        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18627        synchronized (this) {
18628            return stopUserLocked(userId, callback);
18629        }
18630    }
18631
18632    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18633        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18634        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18635            return ActivityManager.USER_OP_IS_CURRENT;
18636        }
18637
18638        final UserStartedState uss = mStartedUsers.get(userId);
18639        if (uss == null) {
18640            // User is not started, nothing to do...  but we do need to
18641            // callback if requested.
18642            if (callback != null) {
18643                mHandler.post(new Runnable() {
18644                    @Override
18645                    public void run() {
18646                        try {
18647                            callback.userStopped(userId);
18648                        } catch (RemoteException e) {
18649                        }
18650                    }
18651                });
18652            }
18653            return ActivityManager.USER_OP_SUCCESS;
18654        }
18655
18656        if (callback != null) {
18657            uss.mStopCallbacks.add(callback);
18658        }
18659
18660        if (uss.mState != UserStartedState.STATE_STOPPING
18661                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18662            uss.mState = UserStartedState.STATE_STOPPING;
18663            updateStartedUserArrayLocked();
18664
18665            long ident = Binder.clearCallingIdentity();
18666            try {
18667                // We are going to broadcast ACTION_USER_STOPPING and then
18668                // once that is done send a final ACTION_SHUTDOWN and then
18669                // stop the user.
18670                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18671                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18672                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18673                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18674                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18675                // This is the result receiver for the final shutdown broadcast.
18676                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18677                    @Override
18678                    public void performReceive(Intent intent, int resultCode, String data,
18679                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18680                        finishUserStop(uss);
18681                    }
18682                };
18683                // This is the result receiver for the initial stopping broadcast.
18684                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18685                    @Override
18686                    public void performReceive(Intent intent, int resultCode, String data,
18687                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18688                        // On to the next.
18689                        synchronized (ActivityManagerService.this) {
18690                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18691                                // Whoops, we are being started back up.  Abort, abort!
18692                                return;
18693                            }
18694                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18695                        }
18696                        mBatteryStatsService.noteEvent(
18697                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18698                                Integer.toString(userId), userId);
18699                        mSystemServiceManager.stopUser(userId);
18700                        broadcastIntentLocked(null, null, shutdownIntent,
18701                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18702                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18703                    }
18704                };
18705                // Kick things off.
18706                broadcastIntentLocked(null, null, stoppingIntent,
18707                        null, stoppingReceiver, 0, null, null,
18708                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18709                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18710            } finally {
18711                Binder.restoreCallingIdentity(ident);
18712            }
18713        }
18714
18715        return ActivityManager.USER_OP_SUCCESS;
18716    }
18717
18718    void finishUserStop(UserStartedState uss) {
18719        final int userId = uss.mHandle.getIdentifier();
18720        boolean stopped;
18721        ArrayList<IStopUserCallback> callbacks;
18722        synchronized (this) {
18723            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18724            if (mStartedUsers.get(userId) != uss) {
18725                stopped = false;
18726            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18727                stopped = false;
18728            } else {
18729                stopped = true;
18730                // User can no longer run.
18731                mStartedUsers.remove(userId);
18732                mUserLru.remove(Integer.valueOf(userId));
18733                updateStartedUserArrayLocked();
18734
18735                // Clean up all state and processes associated with the user.
18736                // Kill all the processes for the user.
18737                forceStopUserLocked(userId, "finish user");
18738            }
18739
18740            // Explicitly remove the old information in mRecentTasks.
18741            removeRecentTasksForUserLocked(userId);
18742        }
18743
18744        for (int i=0; i<callbacks.size(); i++) {
18745            try {
18746                if (stopped) callbacks.get(i).userStopped(userId);
18747                else callbacks.get(i).userStopAborted(userId);
18748            } catch (RemoteException e) {
18749            }
18750        }
18751
18752        if (stopped) {
18753            mSystemServiceManager.cleanupUser(userId);
18754            synchronized (this) {
18755                mStackSupervisor.removeUserLocked(userId);
18756            }
18757        }
18758    }
18759
18760    @Override
18761    public UserInfo getCurrentUser() {
18762        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18763                != PackageManager.PERMISSION_GRANTED) && (
18764                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18765                != PackageManager.PERMISSION_GRANTED)) {
18766            String msg = "Permission Denial: getCurrentUser() from pid="
18767                    + Binder.getCallingPid()
18768                    + ", uid=" + Binder.getCallingUid()
18769                    + " requires " + INTERACT_ACROSS_USERS;
18770            Slog.w(TAG, msg);
18771            throw new SecurityException(msg);
18772        }
18773        synchronized (this) {
18774            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18775            return getUserManagerLocked().getUserInfo(userId);
18776        }
18777    }
18778
18779    int getCurrentUserIdLocked() {
18780        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18781    }
18782
18783    @Override
18784    public boolean isUserRunning(int userId, boolean orStopped) {
18785        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18786                != PackageManager.PERMISSION_GRANTED) {
18787            String msg = "Permission Denial: isUserRunning() from pid="
18788                    + Binder.getCallingPid()
18789                    + ", uid=" + Binder.getCallingUid()
18790                    + " requires " + INTERACT_ACROSS_USERS;
18791            Slog.w(TAG, msg);
18792            throw new SecurityException(msg);
18793        }
18794        synchronized (this) {
18795            return isUserRunningLocked(userId, orStopped);
18796        }
18797    }
18798
18799    boolean isUserRunningLocked(int userId, boolean orStopped) {
18800        UserStartedState state = mStartedUsers.get(userId);
18801        if (state == null) {
18802            return false;
18803        }
18804        if (orStopped) {
18805            return true;
18806        }
18807        return state.mState != UserStartedState.STATE_STOPPING
18808                && state.mState != UserStartedState.STATE_SHUTDOWN;
18809    }
18810
18811    @Override
18812    public int[] getRunningUserIds() {
18813        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18814                != PackageManager.PERMISSION_GRANTED) {
18815            String msg = "Permission Denial: isUserRunning() from pid="
18816                    + Binder.getCallingPid()
18817                    + ", uid=" + Binder.getCallingUid()
18818                    + " requires " + INTERACT_ACROSS_USERS;
18819            Slog.w(TAG, msg);
18820            throw new SecurityException(msg);
18821        }
18822        synchronized (this) {
18823            return mStartedUserArray;
18824        }
18825    }
18826
18827    private void updateStartedUserArrayLocked() {
18828        int num = 0;
18829        for (int i=0; i<mStartedUsers.size();  i++) {
18830            UserStartedState uss = mStartedUsers.valueAt(i);
18831            // This list does not include stopping users.
18832            if (uss.mState != UserStartedState.STATE_STOPPING
18833                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18834                num++;
18835            }
18836        }
18837        mStartedUserArray = new int[num];
18838        num = 0;
18839        for (int i=0; i<mStartedUsers.size();  i++) {
18840            UserStartedState uss = mStartedUsers.valueAt(i);
18841            if (uss.mState != UserStartedState.STATE_STOPPING
18842                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18843                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18844                num++;
18845            }
18846        }
18847    }
18848
18849    @Override
18850    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18851        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18852                != PackageManager.PERMISSION_GRANTED) {
18853            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18854                    + Binder.getCallingPid()
18855                    + ", uid=" + Binder.getCallingUid()
18856                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18857            Slog.w(TAG, msg);
18858            throw new SecurityException(msg);
18859        }
18860
18861        mUserSwitchObservers.register(observer);
18862    }
18863
18864    @Override
18865    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18866        mUserSwitchObservers.unregister(observer);
18867    }
18868
18869    private boolean userExists(int userId) {
18870        if (userId == 0) {
18871            return true;
18872        }
18873        UserManagerService ums = getUserManagerLocked();
18874        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18875    }
18876
18877    int[] getUsersLocked() {
18878        UserManagerService ums = getUserManagerLocked();
18879        return ums != null ? ums.getUserIds() : new int[] { 0 };
18880    }
18881
18882    UserManagerService getUserManagerLocked() {
18883        if (mUserManager == null) {
18884            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18885            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18886        }
18887        return mUserManager;
18888    }
18889
18890    private int applyUserId(int uid, int userId) {
18891        return UserHandle.getUid(userId, uid);
18892    }
18893
18894    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18895        if (info == null) return null;
18896        ApplicationInfo newInfo = new ApplicationInfo(info);
18897        newInfo.uid = applyUserId(info.uid, userId);
18898        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18899                + info.packageName;
18900        return newInfo;
18901    }
18902
18903    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18904        if (aInfo == null
18905                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18906            return aInfo;
18907        }
18908
18909        ActivityInfo info = new ActivityInfo(aInfo);
18910        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18911        return info;
18912    }
18913
18914    private final class LocalService extends ActivityManagerInternal {
18915        @Override
18916        public void goingToSleep() {
18917            ActivityManagerService.this.goingToSleep();
18918        }
18919
18920        @Override
18921        public void wakingUp() {
18922            ActivityManagerService.this.wakingUp();
18923        }
18924
18925        @Override
18926        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18927                String processName, String abiOverride, int uid, Runnable crashHandler) {
18928            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18929                    processName, abiOverride, uid, crashHandler);
18930        }
18931    }
18932
18933    /**
18934     * An implementation of IAppTask, that allows an app to manage its own tasks via
18935     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18936     * only the process that calls getAppTasks() can call the AppTask methods.
18937     */
18938    class AppTaskImpl extends IAppTask.Stub {
18939        private int mTaskId;
18940        private int mCallingUid;
18941
18942        public AppTaskImpl(int taskId, int callingUid) {
18943            mTaskId = taskId;
18944            mCallingUid = callingUid;
18945        }
18946
18947        private void checkCaller() {
18948            if (mCallingUid != Binder.getCallingUid()) {
18949                throw new SecurityException("Caller " + mCallingUid
18950                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18951            }
18952        }
18953
18954        @Override
18955        public void finishAndRemoveTask() {
18956            checkCaller();
18957
18958            synchronized (ActivityManagerService.this) {
18959                long origId = Binder.clearCallingIdentity();
18960                try {
18961                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18962                    if (tr == null) {
18963                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18964                    }
18965                    // Only kill the process if we are not a new document
18966                    int flags = tr.getBaseIntent().getFlags();
18967                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18968                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18969                    removeTaskByIdLocked(mTaskId,
18970                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18971                } finally {
18972                    Binder.restoreCallingIdentity(origId);
18973                }
18974            }
18975        }
18976
18977        @Override
18978        public ActivityManager.RecentTaskInfo getTaskInfo() {
18979            checkCaller();
18980
18981            synchronized (ActivityManagerService.this) {
18982                long origId = Binder.clearCallingIdentity();
18983                try {
18984                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18985                    if (tr == null) {
18986                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18987                    }
18988                    return createRecentTaskInfoFromTaskRecord(tr);
18989                } finally {
18990                    Binder.restoreCallingIdentity(origId);
18991                }
18992            }
18993        }
18994
18995        @Override
18996        public void moveToFront() {
18997            checkCaller();
18998
18999            final TaskRecord tr;
19000            synchronized (ActivityManagerService.this) {
19001                tr = recentTaskForIdLocked(mTaskId);
19002                if (tr == null) {
19003                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19004                }
19005                if (tr.getRootActivity() != null) {
19006                    moveTaskToFrontLocked(tr.taskId, 0, null);
19007                    return;
19008                }
19009            }
19010
19011            startActivityFromRecentsInner(tr.taskId, null);
19012        }
19013
19014        @Override
19015        public int startActivity(IBinder whoThread, String callingPackage,
19016                Intent intent, String resolvedType, Bundle options) {
19017            checkCaller();
19018
19019            int callingUser = UserHandle.getCallingUserId();
19020            TaskRecord tr;
19021            IApplicationThread appThread;
19022            synchronized (ActivityManagerService.this) {
19023                tr = recentTaskForIdLocked(mTaskId);
19024                if (tr == null) {
19025                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19026                }
19027                appThread = ApplicationThreadNative.asInterface(whoThread);
19028                if (appThread == null) {
19029                    throw new IllegalArgumentException("Bad app thread " + appThread);
19030                }
19031            }
19032            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19033                    resolvedType, null, null, null, null, 0, 0, null, null,
19034                    null, options, callingUser, null, tr);
19035        }
19036
19037        @Override
19038        public void setExcludeFromRecents(boolean exclude) {
19039            checkCaller();
19040
19041            synchronized (ActivityManagerService.this) {
19042                long origId = Binder.clearCallingIdentity();
19043                try {
19044                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19045                    if (tr == null) {
19046                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19047                    }
19048                    Intent intent = tr.getBaseIntent();
19049                    if (exclude) {
19050                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19051                    } else {
19052                        intent.setFlags(intent.getFlags()
19053                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19054                    }
19055                } finally {
19056                    Binder.restoreCallingIdentity(origId);
19057                }
19058            }
19059        }
19060    }
19061}
19062