ActivityManagerService.java revision ce0fd7665f297c5693ee23b3d6daf26baeed4e9d
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     * Set while the keyguard is waiting for an activity to draw.
941     * In this state, if we are sleeping, we allow Activities to launch
942     * so that they can draw before Keyguard dismisses itself.
943     */
944    private boolean mKeyguardWaitingForDraw = false;
945
946    /**
947     * State of external calls telling us if the device is asleep.
948     */
949    private boolean mWentToSleep = false;
950
951    /**
952     * State of external call telling us if the lock screen is shown.
953     */
954    private boolean mLockScreenShown = false;
955
956    /**
957     * Set if we are shutting down the system, similar to sleeping.
958     */
959    boolean mShuttingDown = false;
960
961    /**
962     * Current sequence id for oom_adj computation traversal.
963     */
964    int mAdjSeq = 0;
965
966    /**
967     * Current sequence id for process LRU updating.
968     */
969    int mLruSeq = 0;
970
971    /**
972     * Keep track of the non-cached/empty process we last found, to help
973     * determine how to distribute cached/empty processes next time.
974     */
975    int mNumNonCachedProcs = 0;
976
977    /**
978     * Keep track of the number of cached hidden procs, to balance oom adj
979     * distribution between those and empty procs.
980     */
981    int mNumCachedHiddenProcs = 0;
982
983    /**
984     * Keep track of the number of service processes we last found, to
985     * determine on the next iteration which should be B services.
986     */
987    int mNumServiceProcs = 0;
988    int mNewNumAServiceProcs = 0;
989    int mNewNumServiceProcs = 0;
990
991    /**
992     * Allow the current computed overall memory level of the system to go down?
993     * This is set to false when we are killing processes for reasons other than
994     * memory management, so that the now smaller process list will not be taken as
995     * an indication that memory is tighter.
996     */
997    boolean mAllowLowerMemLevel = false;
998
999    /**
1000     * The last computed memory level, for holding when we are in a state that
1001     * processes are going away for other reasons.
1002     */
1003    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1004
1005    /**
1006     * The last total number of process we have, to determine if changes actually look
1007     * like a shrinking number of process due to lower RAM.
1008     */
1009    int mLastNumProcesses;
1010
1011    /**
1012     * The uptime of the last time we performed idle maintenance.
1013     */
1014    long mLastIdleTime = SystemClock.uptimeMillis();
1015
1016    /**
1017     * Total time spent with RAM that has been added in the past since the last idle time.
1018     */
1019    long mLowRamTimeSinceLastIdle = 0;
1020
1021    /**
1022     * If RAM is currently low, when that horrible situation started.
1023     */
1024    long mLowRamStartTime = 0;
1025
1026    /**
1027     * For reporting to battery stats the current top application.
1028     */
1029    private String mCurResumedPackage = null;
1030    private int mCurResumedUid = -1;
1031
1032    /**
1033     * For reporting to battery stats the apps currently running foreground
1034     * service.  The ProcessMap is package/uid tuples; each of these contain
1035     * an array of the currently foreground processes.
1036     */
1037    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1038            = new ProcessMap<ArrayList<ProcessRecord>>();
1039
1040    /**
1041     * This is set if we had to do a delayed dexopt of an app before launching
1042     * it, to increase the ANR timeouts in that case.
1043     */
1044    boolean mDidDexOpt;
1045
1046    /**
1047     * Set if the systemServer made a call to enterSafeMode.
1048     */
1049    boolean mSafeMode;
1050
1051    String mDebugApp = null;
1052    boolean mWaitForDebugger = false;
1053    boolean mDebugTransient = false;
1054    String mOrigDebugApp = null;
1055    boolean mOrigWaitForDebugger = false;
1056    boolean mAlwaysFinishActivities = false;
1057    IActivityController mController = null;
1058    String mProfileApp = null;
1059    ProcessRecord mProfileProc = null;
1060    String mProfileFile;
1061    ParcelFileDescriptor mProfileFd;
1062    int mSamplingInterval = 0;
1063    boolean mAutoStopProfiler = false;
1064    int mProfileType = 0;
1065    String mOpenGlTraceApp = null;
1066
1067    static class ProcessChangeItem {
1068        static final int CHANGE_ACTIVITIES = 1<<0;
1069        static final int CHANGE_PROCESS_STATE = 1<<1;
1070        int changes;
1071        int uid;
1072        int pid;
1073        int processState;
1074        boolean foregroundActivities;
1075    }
1076
1077    final RemoteCallbackList<IProcessObserver> mProcessObservers
1078            = new RemoteCallbackList<IProcessObserver>();
1079    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1080
1081    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1082            = new ArrayList<ProcessChangeItem>();
1083    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1084            = new ArrayList<ProcessChangeItem>();
1085
1086    /**
1087     * Runtime CPU use collection thread.  This object's lock is used to
1088     * perform synchronization with the thread (notifying it to run).
1089     */
1090    final Thread mProcessCpuThread;
1091
1092    /**
1093     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1094     * Must acquire this object's lock when accessing it.
1095     * NOTE: this lock will be held while doing long operations (trawling
1096     * through all processes in /proc), so it should never be acquired by
1097     * any critical paths such as when holding the main activity manager lock.
1098     */
1099    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1100            MONITOR_THREAD_CPU_USAGE);
1101    final AtomicLong mLastCpuTime = new AtomicLong(0);
1102    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1103
1104    long mLastWriteTime = 0;
1105
1106    /**
1107     * Used to retain an update lock when the foreground activity is in
1108     * immersive mode.
1109     */
1110    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1111
1112    /**
1113     * Set to true after the system has finished booting.
1114     */
1115    boolean mBooted = false;
1116
1117    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1118    int mProcessLimitOverride = -1;
1119
1120    WindowManagerService mWindowManager;
1121
1122    final ActivityThread mSystemThread;
1123
1124    // Holds the current foreground user's id
1125    int mCurrentUserId = 0;
1126    // Holds the target user's id during a user switch
1127    int mTargetUserId = UserHandle.USER_NULL;
1128    // If there are multiple profiles for the current user, their ids are here
1129    // Currently only the primary user can have managed profiles
1130    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1131
1132    /**
1133     * Mapping from each known user ID to the profile group ID it is associated with.
1134     */
1135    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1136
1137    private UserManagerService mUserManager;
1138
1139    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1140        final ProcessRecord mApp;
1141        final int mPid;
1142        final IApplicationThread mAppThread;
1143
1144        AppDeathRecipient(ProcessRecord app, int pid,
1145                IApplicationThread thread) {
1146            if (localLOGV) Slog.v(
1147                TAG, "New death recipient " + this
1148                + " for thread " + thread.asBinder());
1149            mApp = app;
1150            mPid = pid;
1151            mAppThread = thread;
1152        }
1153
1154        @Override
1155        public void binderDied() {
1156            if (localLOGV) Slog.v(
1157                TAG, "Death received in " + this
1158                + " for thread " + mAppThread.asBinder());
1159            synchronized(ActivityManagerService.this) {
1160                appDiedLocked(mApp, mPid, mAppThread);
1161            }
1162        }
1163    }
1164
1165    static final int SHOW_ERROR_MSG = 1;
1166    static final int SHOW_NOT_RESPONDING_MSG = 2;
1167    static final int SHOW_FACTORY_ERROR_MSG = 3;
1168    static final int UPDATE_CONFIGURATION_MSG = 4;
1169    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1170    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1171    static final int SERVICE_TIMEOUT_MSG = 12;
1172    static final int UPDATE_TIME_ZONE = 13;
1173    static final int SHOW_UID_ERROR_MSG = 14;
1174    static final int IM_FEELING_LUCKY_MSG = 15;
1175    static final int PROC_START_TIMEOUT_MSG = 20;
1176    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1177    static final int KILL_APPLICATION_MSG = 22;
1178    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1179    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1180    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1181    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1182    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1183    static final int CLEAR_DNS_CACHE_MSG = 28;
1184    static final int UPDATE_HTTP_PROXY_MSG = 29;
1185    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1186    static final int DISPATCH_PROCESSES_CHANGED = 31;
1187    static final int DISPATCH_PROCESS_DIED = 32;
1188    static final int REPORT_MEM_USAGE_MSG = 33;
1189    static final int REPORT_USER_SWITCH_MSG = 34;
1190    static final int CONTINUE_USER_SWITCH_MSG = 35;
1191    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1192    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1193    static final int PERSIST_URI_GRANTS_MSG = 38;
1194    static final int REQUEST_ALL_PSS_MSG = 39;
1195    static final int START_PROFILES_MSG = 40;
1196    static final int UPDATE_TIME = 41;
1197    static final int SYSTEM_USER_START_MSG = 42;
1198    static final int SYSTEM_USER_CURRENT_MSG = 43;
1199    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1200    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1201    static final int START_USER_SWITCH_MSG = 46;
1202
1203    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1204    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1205    static final int FIRST_COMPAT_MODE_MSG = 300;
1206    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1207
1208    AlertDialog mUidAlert;
1209    CompatModeDialog mCompatModeDialog;
1210    long mLastMemUsageReportTime = 0;
1211
1212    private LockToAppRequestDialog mLockToAppRequest;
1213
1214    /**
1215     * Flag whether the current user is a "monkey", i.e. whether
1216     * the UI is driven by a UI automation tool.
1217     */
1218    private boolean mUserIsMonkey;
1219
1220    /** Flag whether the device has a Recents UI */
1221    boolean mHasRecents;
1222
1223    /** The dimensions of the thumbnails in the Recents UI. */
1224    int mThumbnailWidth;
1225    int mThumbnailHeight;
1226
1227    final ServiceThread mHandlerThread;
1228    final MainHandler mHandler;
1229
1230    final class MainHandler extends Handler {
1231        public MainHandler(Looper looper) {
1232            super(looper, null, true);
1233        }
1234
1235        @Override
1236        public void handleMessage(Message msg) {
1237            switch (msg.what) {
1238            case SHOW_ERROR_MSG: {
1239                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1240                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1241                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1242                synchronized (ActivityManagerService.this) {
1243                    ProcessRecord proc = (ProcessRecord)data.get("app");
1244                    AppErrorResult res = (AppErrorResult) data.get("result");
1245                    if (proc != null && proc.crashDialog != null) {
1246                        Slog.e(TAG, "App already has crash dialog: " + proc);
1247                        if (res != null) {
1248                            res.set(0);
1249                        }
1250                        return;
1251                    }
1252                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1253                            >= Process.FIRST_APPLICATION_UID
1254                            && proc.pid != MY_PID);
1255                    for (int userId : mCurrentProfileIds) {
1256                        isBackground &= (proc.userId != userId);
1257                    }
1258                    if (isBackground && !showBackground) {
1259                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1260                        if (res != null) {
1261                            res.set(0);
1262                        }
1263                        return;
1264                    }
1265                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1266                        Dialog d = new AppErrorDialog(mContext,
1267                                ActivityManagerService.this, res, proc);
1268                        d.show();
1269                        proc.crashDialog = d;
1270                    } else {
1271                        // The device is asleep, so just pretend that the user
1272                        // saw a crash dialog and hit "force quit".
1273                        if (res != null) {
1274                            res.set(0);
1275                        }
1276                    }
1277                }
1278
1279                ensureBootCompleted();
1280            } break;
1281            case SHOW_NOT_RESPONDING_MSG: {
1282                synchronized (ActivityManagerService.this) {
1283                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1284                    ProcessRecord proc = (ProcessRecord)data.get("app");
1285                    if (proc != null && proc.anrDialog != null) {
1286                        Slog.e(TAG, "App already has anr dialog: " + proc);
1287                        return;
1288                    }
1289
1290                    Intent intent = new Intent("android.intent.action.ANR");
1291                    if (!mProcessesReady) {
1292                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1293                                | Intent.FLAG_RECEIVER_FOREGROUND);
1294                    }
1295                    broadcastIntentLocked(null, null, intent,
1296                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1297                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1298
1299                    if (mShowDialogs) {
1300                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1301                                mContext, proc, (ActivityRecord)data.get("activity"),
1302                                msg.arg1 != 0);
1303                        d.show();
1304                        proc.anrDialog = d;
1305                    } else {
1306                        // Just kill the app if there is no dialog to be shown.
1307                        killAppAtUsersRequest(proc, null);
1308                    }
1309                }
1310
1311                ensureBootCompleted();
1312            } break;
1313            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1314                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1315                synchronized (ActivityManagerService.this) {
1316                    ProcessRecord proc = (ProcessRecord) data.get("app");
1317                    if (proc == null) {
1318                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1319                        break;
1320                    }
1321                    if (proc.crashDialog != null) {
1322                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1323                        return;
1324                    }
1325                    AppErrorResult res = (AppErrorResult) data.get("result");
1326                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1327                        Dialog d = new StrictModeViolationDialog(mContext,
1328                                ActivityManagerService.this, res, proc);
1329                        d.show();
1330                        proc.crashDialog = d;
1331                    } else {
1332                        // The device is asleep, so just pretend that the user
1333                        // saw a crash dialog and hit "force quit".
1334                        res.set(0);
1335                    }
1336                }
1337                ensureBootCompleted();
1338            } break;
1339            case SHOW_FACTORY_ERROR_MSG: {
1340                Dialog d = new FactoryErrorDialog(
1341                    mContext, msg.getData().getCharSequence("msg"));
1342                d.show();
1343                ensureBootCompleted();
1344            } break;
1345            case UPDATE_CONFIGURATION_MSG: {
1346                final ContentResolver resolver = mContext.getContentResolver();
1347                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1348            } break;
1349            case GC_BACKGROUND_PROCESSES_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    performAppGcsIfAppropriateLocked();
1352                }
1353            } break;
1354            case WAIT_FOR_DEBUGGER_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    ProcessRecord app = (ProcessRecord)msg.obj;
1357                    if (msg.arg1 != 0) {
1358                        if (!app.waitedForDebugger) {
1359                            Dialog d = new AppWaitingForDebuggerDialog(
1360                                    ActivityManagerService.this,
1361                                    mContext, app);
1362                            app.waitDialog = d;
1363                            app.waitedForDebugger = true;
1364                            d.show();
1365                        }
1366                    } else {
1367                        if (app.waitDialog != null) {
1368                            app.waitDialog.dismiss();
1369                            app.waitDialog = null;
1370                        }
1371                    }
1372                }
1373            } break;
1374            case SERVICE_TIMEOUT_MSG: {
1375                if (mDidDexOpt) {
1376                    mDidDexOpt = false;
1377                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1378                    nmsg.obj = msg.obj;
1379                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1380                    return;
1381                }
1382                mServices.serviceTimeout((ProcessRecord)msg.obj);
1383            } break;
1384            case UPDATE_TIME_ZONE: {
1385                synchronized (ActivityManagerService.this) {
1386                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1387                        ProcessRecord r = mLruProcesses.get(i);
1388                        if (r.thread != null) {
1389                            try {
1390                                r.thread.updateTimeZone();
1391                            } catch (RemoteException ex) {
1392                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1393                            }
1394                        }
1395                    }
1396                }
1397            } break;
1398            case CLEAR_DNS_CACHE_MSG: {
1399                synchronized (ActivityManagerService.this) {
1400                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1401                        ProcessRecord r = mLruProcesses.get(i);
1402                        if (r.thread != null) {
1403                            try {
1404                                r.thread.clearDnsCache();
1405                            } catch (RemoteException ex) {
1406                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1407                            }
1408                        }
1409                    }
1410                }
1411            } break;
1412            case UPDATE_HTTP_PROXY_MSG: {
1413                ProxyInfo proxy = (ProxyInfo)msg.obj;
1414                String host = "";
1415                String port = "";
1416                String exclList = "";
1417                Uri pacFileUrl = Uri.EMPTY;
1418                if (proxy != null) {
1419                    host = proxy.getHost();
1420                    port = Integer.toString(proxy.getPort());
1421                    exclList = proxy.getExclusionListAsString();
1422                    pacFileUrl = proxy.getPacFileUrl();
1423                }
1424                synchronized (ActivityManagerService.this) {
1425                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1426                        ProcessRecord r = mLruProcesses.get(i);
1427                        if (r.thread != null) {
1428                            try {
1429                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1430                            } catch (RemoteException ex) {
1431                                Slog.w(TAG, "Failed to update http proxy for: " +
1432                                        r.info.processName);
1433                            }
1434                        }
1435                    }
1436                }
1437            } break;
1438            case SHOW_UID_ERROR_MSG: {
1439                String title = "System UIDs Inconsistent";
1440                String text = "UIDs on the system are inconsistent, you need to wipe your"
1441                        + " data partition or your device will be unstable.";
1442                Log.e(TAG, title + ": " + text);
1443                if (mShowDialogs) {
1444                    // XXX This is a temporary dialog, no need to localize.
1445                    AlertDialog d = new BaseErrorDialog(mContext);
1446                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1447                    d.setCancelable(false);
1448                    d.setTitle(title);
1449                    d.setMessage(text);
1450                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1451                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1452                    mUidAlert = d;
1453                    d.show();
1454                }
1455            } break;
1456            case IM_FEELING_LUCKY_MSG: {
1457                if (mUidAlert != null) {
1458                    mUidAlert.dismiss();
1459                    mUidAlert = null;
1460                }
1461            } break;
1462            case PROC_START_TIMEOUT_MSG: {
1463                if (mDidDexOpt) {
1464                    mDidDexOpt = false;
1465                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1466                    nmsg.obj = msg.obj;
1467                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1468                    return;
1469                }
1470                ProcessRecord app = (ProcessRecord)msg.obj;
1471                synchronized (ActivityManagerService.this) {
1472                    processStartTimedOutLocked(app);
1473                }
1474            } break;
1475            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1476                synchronized (ActivityManagerService.this) {
1477                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1478                }
1479            } break;
1480            case KILL_APPLICATION_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    int appid = msg.arg1;
1483                    boolean restart = (msg.arg2 == 1);
1484                    Bundle bundle = (Bundle)msg.obj;
1485                    String pkg = bundle.getString("pkg");
1486                    String reason = bundle.getString("reason");
1487                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1488                            false, UserHandle.USER_ALL, reason);
1489                }
1490            } break;
1491            case FINALIZE_PENDING_INTENT_MSG: {
1492                ((PendingIntentRecord)msg.obj).completeFinalize();
1493            } break;
1494            case POST_HEAVY_NOTIFICATION_MSG: {
1495                INotificationManager inm = NotificationManager.getService();
1496                if (inm == null) {
1497                    return;
1498                }
1499
1500                ActivityRecord root = (ActivityRecord)msg.obj;
1501                ProcessRecord process = root.app;
1502                if (process == null) {
1503                    return;
1504                }
1505
1506                try {
1507                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1508                    String text = mContext.getString(R.string.heavy_weight_notification,
1509                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1510                    Notification notification = new Notification();
1511                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1512                    notification.when = 0;
1513                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1514                    notification.tickerText = text;
1515                    notification.defaults = 0; // please be quiet
1516                    notification.sound = null;
1517                    notification.vibrate = null;
1518                    notification.color = mContext.getResources().getColor(
1519                            com.android.internal.R.color.system_notification_accent_color);
1520                    notification.setLatestEventInfo(context, text,
1521                            mContext.getText(R.string.heavy_weight_notification_detail),
1522                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1523                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1524                                    new UserHandle(root.userId)));
1525
1526                    try {
1527                        int[] outId = new int[1];
1528                        inm.enqueueNotificationWithTag("android", "android", null,
1529                                R.string.heavy_weight_notification,
1530                                notification, outId, root.userId);
1531                    } catch (RuntimeException e) {
1532                        Slog.w(ActivityManagerService.TAG,
1533                                "Error showing notification for heavy-weight app", e);
1534                    } catch (RemoteException e) {
1535                    }
1536                } catch (NameNotFoundException e) {
1537                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1538                }
1539            } break;
1540            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1541                INotificationManager inm = NotificationManager.getService();
1542                if (inm == null) {
1543                    return;
1544                }
1545                try {
1546                    inm.cancelNotificationWithTag("android", null,
1547                            R.string.heavy_weight_notification,  msg.arg1);
1548                } catch (RuntimeException e) {
1549                    Slog.w(ActivityManagerService.TAG,
1550                            "Error canceling notification for service", e);
1551                } catch (RemoteException e) {
1552                }
1553            } break;
1554            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1555                synchronized (ActivityManagerService.this) {
1556                    checkExcessivePowerUsageLocked(true);
1557                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1558                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1559                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1560                }
1561            } break;
1562            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1563                synchronized (ActivityManagerService.this) {
1564                    ActivityRecord ar = (ActivityRecord)msg.obj;
1565                    if (mCompatModeDialog != null) {
1566                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1567                                ar.info.applicationInfo.packageName)) {
1568                            return;
1569                        }
1570                        mCompatModeDialog.dismiss();
1571                        mCompatModeDialog = null;
1572                    }
1573                    if (ar != null && false) {
1574                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1575                                ar.packageName)) {
1576                            int mode = mCompatModePackages.computeCompatModeLocked(
1577                                    ar.info.applicationInfo);
1578                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1579                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1580                                mCompatModeDialog = new CompatModeDialog(
1581                                        ActivityManagerService.this, mContext,
1582                                        ar.info.applicationInfo);
1583                                mCompatModeDialog.show();
1584                            }
1585                        }
1586                    }
1587                }
1588                break;
1589            }
1590            case DISPATCH_PROCESSES_CHANGED: {
1591                dispatchProcessesChanged();
1592                break;
1593            }
1594            case DISPATCH_PROCESS_DIED: {
1595                final int pid = msg.arg1;
1596                final int uid = msg.arg2;
1597                dispatchProcessDied(pid, uid);
1598                break;
1599            }
1600            case REPORT_MEM_USAGE_MSG: {
1601                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1602                Thread thread = new Thread() {
1603                    @Override public void run() {
1604                        final SparseArray<ProcessMemInfo> infoMap
1605                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1606                        for (int i=0, N=memInfos.size(); i<N; i++) {
1607                            ProcessMemInfo mi = memInfos.get(i);
1608                            infoMap.put(mi.pid, mi);
1609                        }
1610                        updateCpuStatsNow();
1611                        synchronized (mProcessCpuTracker) {
1612                            final int N = mProcessCpuTracker.countStats();
1613                            for (int i=0; i<N; i++) {
1614                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1615                                if (st.vsize > 0) {
1616                                    long pss = Debug.getPss(st.pid, null);
1617                                    if (pss > 0) {
1618                                        if (infoMap.indexOfKey(st.pid) < 0) {
1619                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1620                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1621                                            mi.pss = pss;
1622                                            memInfos.add(mi);
1623                                        }
1624                                    }
1625                                }
1626                            }
1627                        }
1628
1629                        long totalPss = 0;
1630                        for (int i=0, N=memInfos.size(); i<N; i++) {
1631                            ProcessMemInfo mi = memInfos.get(i);
1632                            if (mi.pss == 0) {
1633                                mi.pss = Debug.getPss(mi.pid, null);
1634                            }
1635                            totalPss += mi.pss;
1636                        }
1637                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1638                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1639                                if (lhs.oomAdj != rhs.oomAdj) {
1640                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1641                                }
1642                                if (lhs.pss != rhs.pss) {
1643                                    return lhs.pss < rhs.pss ? 1 : -1;
1644                                }
1645                                return 0;
1646                            }
1647                        });
1648
1649                        StringBuilder tag = new StringBuilder(128);
1650                        StringBuilder stack = new StringBuilder(128);
1651                        tag.append("Low on memory -- ");
1652                        appendMemBucket(tag, totalPss, "total", false);
1653                        appendMemBucket(stack, totalPss, "total", true);
1654
1655                        StringBuilder logBuilder = new StringBuilder(1024);
1656                        logBuilder.append("Low on memory:\n");
1657
1658                        boolean firstLine = true;
1659                        int lastOomAdj = Integer.MIN_VALUE;
1660                        for (int i=0, N=memInfos.size(); i<N; i++) {
1661                            ProcessMemInfo mi = memInfos.get(i);
1662
1663                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1664                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1665                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1666                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1667                                if (lastOomAdj != mi.oomAdj) {
1668                                    lastOomAdj = mi.oomAdj;
1669                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1670                                        tag.append(" / ");
1671                                    }
1672                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1673                                        if (firstLine) {
1674                                            stack.append(":");
1675                                            firstLine = false;
1676                                        }
1677                                        stack.append("\n\t at ");
1678                                    } else {
1679                                        stack.append("$");
1680                                    }
1681                                } else {
1682                                    tag.append(" ");
1683                                    stack.append("$");
1684                                }
1685                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1686                                    appendMemBucket(tag, mi.pss, mi.name, false);
1687                                }
1688                                appendMemBucket(stack, mi.pss, mi.name, true);
1689                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1690                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1691                                    stack.append("(");
1692                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1693                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1694                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1695                                            stack.append(":");
1696                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1697                                        }
1698                                    }
1699                                    stack.append(")");
1700                                }
1701                            }
1702
1703                            logBuilder.append("  ");
1704                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1705                            logBuilder.append(' ');
1706                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1707                            logBuilder.append(' ');
1708                            ProcessList.appendRamKb(logBuilder, mi.pss);
1709                            logBuilder.append(" kB: ");
1710                            logBuilder.append(mi.name);
1711                            logBuilder.append(" (");
1712                            logBuilder.append(mi.pid);
1713                            logBuilder.append(") ");
1714                            logBuilder.append(mi.adjType);
1715                            logBuilder.append('\n');
1716                            if (mi.adjReason != null) {
1717                                logBuilder.append("                      ");
1718                                logBuilder.append(mi.adjReason);
1719                                logBuilder.append('\n');
1720                            }
1721                        }
1722
1723                        logBuilder.append("           ");
1724                        ProcessList.appendRamKb(logBuilder, totalPss);
1725                        logBuilder.append(" kB: TOTAL\n");
1726
1727                        long[] infos = new long[Debug.MEMINFO_COUNT];
1728                        Debug.getMemInfo(infos);
1729                        logBuilder.append("  MemInfo: ");
1730                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1731                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1732                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1733                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1734                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1735                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1736                            logBuilder.append("  ZRAM: ");
1737                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1738                            logBuilder.append(" kB RAM, ");
1739                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1740                            logBuilder.append(" kB swap total, ");
1741                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1742                            logBuilder.append(" kB swap free\n");
1743                        }
1744                        Slog.i(TAG, logBuilder.toString());
1745
1746                        StringBuilder dropBuilder = new StringBuilder(1024);
1747                        /*
1748                        StringWriter oomSw = new StringWriter();
1749                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1750                        StringWriter catSw = new StringWriter();
1751                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1752                        String[] emptyArgs = new String[] { };
1753                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1754                        oomPw.flush();
1755                        String oomString = oomSw.toString();
1756                        */
1757                        dropBuilder.append(stack);
1758                        dropBuilder.append('\n');
1759                        dropBuilder.append('\n');
1760                        dropBuilder.append(logBuilder);
1761                        dropBuilder.append('\n');
1762                        /*
1763                        dropBuilder.append(oomString);
1764                        dropBuilder.append('\n');
1765                        */
1766                        StringWriter catSw = new StringWriter();
1767                        synchronized (ActivityManagerService.this) {
1768                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1769                            String[] emptyArgs = new String[] { };
1770                            catPw.println();
1771                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1772                            catPw.println();
1773                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1774                                    false, false, null);
1775                            catPw.println();
1776                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1777                            catPw.flush();
1778                        }
1779                        dropBuilder.append(catSw.toString());
1780                        addErrorToDropBox("lowmem", null, "system_server", null,
1781                                null, tag.toString(), dropBuilder.toString(), null, null);
1782                        //Slog.i(TAG, "Sent to dropbox:");
1783                        //Slog.i(TAG, dropBuilder.toString());
1784                        synchronized (ActivityManagerService.this) {
1785                            long now = SystemClock.uptimeMillis();
1786                            if (mLastMemUsageReportTime < now) {
1787                                mLastMemUsageReportTime = now;
1788                            }
1789                        }
1790                    }
1791                };
1792                thread.start();
1793                break;
1794            }
1795            case START_USER_SWITCH_MSG: {
1796                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1797                break;
1798            }
1799            case REPORT_USER_SWITCH_MSG: {
1800                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1801                break;
1802            }
1803            case CONTINUE_USER_SWITCH_MSG: {
1804                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1805                break;
1806            }
1807            case USER_SWITCH_TIMEOUT_MSG: {
1808                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1809                break;
1810            }
1811            case IMMERSIVE_MODE_LOCK_MSG: {
1812                final boolean nextState = (msg.arg1 != 0);
1813                if (mUpdateLock.isHeld() != nextState) {
1814                    if (DEBUG_IMMERSIVE) {
1815                        final ActivityRecord r = (ActivityRecord) msg.obj;
1816                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1817                    }
1818                    if (nextState) {
1819                        mUpdateLock.acquire();
1820                    } else {
1821                        mUpdateLock.release();
1822                    }
1823                }
1824                break;
1825            }
1826            case PERSIST_URI_GRANTS_MSG: {
1827                writeGrantedUriPermissions();
1828                break;
1829            }
1830            case REQUEST_ALL_PSS_MSG: {
1831                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1832                break;
1833            }
1834            case START_PROFILES_MSG: {
1835                synchronized (ActivityManagerService.this) {
1836                    startProfilesLocked();
1837                }
1838                break;
1839            }
1840            case UPDATE_TIME: {
1841                synchronized (ActivityManagerService.this) {
1842                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1843                        ProcessRecord r = mLruProcesses.get(i);
1844                        if (r.thread != null) {
1845                            try {
1846                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1847                            } catch (RemoteException ex) {
1848                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1849                            }
1850                        }
1851                    }
1852                }
1853                break;
1854            }
1855            case SYSTEM_USER_START_MSG: {
1856                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1857                        Integer.toString(msg.arg1), msg.arg1);
1858                mSystemServiceManager.startUser(msg.arg1);
1859                break;
1860            }
1861            case SYSTEM_USER_CURRENT_MSG: {
1862                mBatteryStatsService.noteEvent(
1863                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1864                        Integer.toString(msg.arg2), msg.arg2);
1865                mBatteryStatsService.noteEvent(
1866                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1867                        Integer.toString(msg.arg1), msg.arg1);
1868                mSystemServiceManager.switchUser(msg.arg1);
1869                mLockToAppRequest.clearPrompt();
1870                break;
1871            }
1872            case ENTER_ANIMATION_COMPLETE_MSG: {
1873                synchronized (ActivityManagerService.this) {
1874                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1875                    if (r != null && r.app != null && r.app.thread != null) {
1876                        try {
1877                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1878                        } catch (RemoteException e) {
1879                        }
1880                    }
1881                }
1882                break;
1883            }
1884            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1885                enableScreenAfterBoot();
1886                break;
1887            }
1888            }
1889        }
1890    };
1891
1892    static final int COLLECT_PSS_BG_MSG = 1;
1893
1894    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1895        @Override
1896        public void handleMessage(Message msg) {
1897            switch (msg.what) {
1898            case COLLECT_PSS_BG_MSG: {
1899                long start = SystemClock.uptimeMillis();
1900                MemInfoReader memInfo = null;
1901                synchronized (ActivityManagerService.this) {
1902                    if (mFullPssPending) {
1903                        mFullPssPending = false;
1904                        memInfo = new MemInfoReader();
1905                    }
1906                }
1907                if (memInfo != null) {
1908                    updateCpuStatsNow();
1909                    long nativeTotalPss = 0;
1910                    synchronized (mProcessCpuTracker) {
1911                        final int N = mProcessCpuTracker.countStats();
1912                        for (int j=0; j<N; j++) {
1913                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1914                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1915                                // This is definitely an application process; skip it.
1916                                continue;
1917                            }
1918                            synchronized (mPidsSelfLocked) {
1919                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1920                                    // This is one of our own processes; skip it.
1921                                    continue;
1922                                }
1923                            }
1924                            nativeTotalPss += Debug.getPss(st.pid, null);
1925                        }
1926                    }
1927                    memInfo.readMemInfo();
1928                    synchronized (ActivityManagerService.this) {
1929                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1930                                + (SystemClock.uptimeMillis()-start) + "ms");
1931                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1932                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1933                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1934                                        +memInfo.getSlabSizeKb(),
1935                                nativeTotalPss);
1936                    }
1937                }
1938
1939                int i=0, num=0;
1940                long[] tmp = new long[1];
1941                do {
1942                    ProcessRecord proc;
1943                    int procState;
1944                    int pid;
1945                    synchronized (ActivityManagerService.this) {
1946                        if (i >= mPendingPssProcesses.size()) {
1947                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1948                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1949                            mPendingPssProcesses.clear();
1950                            return;
1951                        }
1952                        proc = mPendingPssProcesses.get(i);
1953                        procState = proc.pssProcState;
1954                        if (proc.thread != null && procState == proc.setProcState) {
1955                            pid = proc.pid;
1956                        } else {
1957                            proc = null;
1958                            pid = 0;
1959                        }
1960                        i++;
1961                    }
1962                    if (proc != null) {
1963                        long pss = Debug.getPss(pid, tmp);
1964                        synchronized (ActivityManagerService.this) {
1965                            if (proc.thread != null && proc.setProcState == procState
1966                                    && proc.pid == pid) {
1967                                num++;
1968                                proc.lastPssTime = SystemClock.uptimeMillis();
1969                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1970                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1971                                        + ": " + pss + " lastPss=" + proc.lastPss
1972                                        + " state=" + ProcessList.makeProcStateString(procState));
1973                                if (proc.initialIdlePss == 0) {
1974                                    proc.initialIdlePss = pss;
1975                                }
1976                                proc.lastPss = pss;
1977                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1978                                    proc.lastCachedPss = pss;
1979                                }
1980                            }
1981                        }
1982                    }
1983                } while (true);
1984            }
1985            }
1986        }
1987    };
1988
1989    /**
1990     * Monitor for package changes and update our internal state.
1991     */
1992    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1993        @Override
1994        public void onPackageRemoved(String packageName, int uid) {
1995            // Remove all tasks with activities in the specified package from the list of recent tasks
1996            synchronized (ActivityManagerService.this) {
1997                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1998                    TaskRecord tr = mRecentTasks.get(i);
1999                    ComponentName cn = tr.intent.getComponent();
2000                    if (cn != null && cn.getPackageName().equals(packageName)) {
2001                        // If the package name matches, remove the task and kill the process
2002                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2003                    }
2004                }
2005            }
2006        }
2007
2008        @Override
2009        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2010            onPackageModified(packageName);
2011            return true;
2012        }
2013
2014        @Override
2015        public void onPackageModified(String packageName) {
2016            final PackageManager pm = mContext.getPackageManager();
2017            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2018                    new ArrayList<Pair<Intent, Integer>>();
2019            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2020            // Copy the list of recent tasks so that we don't hold onto the lock on
2021            // ActivityManagerService for long periods while checking if components exist.
2022            synchronized (ActivityManagerService.this) {
2023                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2024                    TaskRecord tr = mRecentTasks.get(i);
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            Intent tmpI = new Intent();
2030            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2031                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2032                ComponentName cn = p.first.getComponent();
2033                if (cn != null && cn.getPackageName().equals(packageName)) {
2034                    try {
2035                        // Add the task to the list to remove if the component no longer exists
2036                        tmpI.setComponent(cn);
2037                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2038                            tasksToRemove.add(p.second);
2039                        }
2040                    } catch (Exception e) {}
2041                }
2042            }
2043            // Prune all the tasks with removed components from the list of recent tasks
2044            synchronized (ActivityManagerService.this) {
2045                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2046                    // Remove the task but don't kill the process (since other components in that
2047                    // package may still be running and in the background)
2048                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2049                }
2050            }
2051        }
2052
2053        @Override
2054        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2055            // Force stop the specified packages
2056            if (packages != null) {
2057                for (String pkg : packages) {
2058                    synchronized (ActivityManagerService.this) {
2059                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2060                                "finished booting")) {
2061                            return true;
2062                        }
2063                    }
2064                }
2065            }
2066            return false;
2067        }
2068    };
2069
2070    public void setSystemProcess() {
2071        try {
2072            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2073            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2074            ServiceManager.addService("meminfo", new MemBinder(this));
2075            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2076            ServiceManager.addService("dbinfo", new DbBinder(this));
2077            if (MONITOR_CPU_USAGE) {
2078                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2079            }
2080            ServiceManager.addService("permission", new PermissionController(this));
2081
2082            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2083                    "android", STOCK_PM_FLAGS);
2084            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2085
2086            synchronized (this) {
2087                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2088                app.persistent = true;
2089                app.pid = MY_PID;
2090                app.maxAdj = ProcessList.SYSTEM_ADJ;
2091                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2092                mProcessNames.put(app.processName, app.uid, app);
2093                synchronized (mPidsSelfLocked) {
2094                    mPidsSelfLocked.put(app.pid, app);
2095                }
2096                updateLruProcessLocked(app, false, null);
2097                updateOomAdjLocked();
2098            }
2099        } catch (PackageManager.NameNotFoundException e) {
2100            throw new RuntimeException(
2101                    "Unable to find android system package", e);
2102        }
2103    }
2104
2105    public void setWindowManager(WindowManagerService wm) {
2106        mWindowManager = wm;
2107        mStackSupervisor.setWindowManager(wm);
2108    }
2109
2110    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2111        mUsageStatsService = usageStatsManager;
2112    }
2113
2114    public void startObservingNativeCrashes() {
2115        final NativeCrashListener ncl = new NativeCrashListener(this);
2116        ncl.start();
2117    }
2118
2119    public IAppOpsService getAppOpsService() {
2120        return mAppOpsService;
2121    }
2122
2123    static class MemBinder extends Binder {
2124        ActivityManagerService mActivityManagerService;
2125        MemBinder(ActivityManagerService activityManagerService) {
2126            mActivityManagerService = activityManagerService;
2127        }
2128
2129        @Override
2130        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2131            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2132                    != PackageManager.PERMISSION_GRANTED) {
2133                pw.println("Permission Denial: can't dump meminfo from from pid="
2134                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2135                        + " without permission " + android.Manifest.permission.DUMP);
2136                return;
2137            }
2138
2139            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2140        }
2141    }
2142
2143    static class GraphicsBinder extends Binder {
2144        ActivityManagerService mActivityManagerService;
2145        GraphicsBinder(ActivityManagerService activityManagerService) {
2146            mActivityManagerService = activityManagerService;
2147        }
2148
2149        @Override
2150        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2151            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2152                    != PackageManager.PERMISSION_GRANTED) {
2153                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2154                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2155                        + " without permission " + android.Manifest.permission.DUMP);
2156                return;
2157            }
2158
2159            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2160        }
2161    }
2162
2163    static class DbBinder extends Binder {
2164        ActivityManagerService mActivityManagerService;
2165        DbBinder(ActivityManagerService activityManagerService) {
2166            mActivityManagerService = activityManagerService;
2167        }
2168
2169        @Override
2170        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2171            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2172                    != PackageManager.PERMISSION_GRANTED) {
2173                pw.println("Permission Denial: can't dump dbinfo from from pid="
2174                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2175                        + " without permission " + android.Manifest.permission.DUMP);
2176                return;
2177            }
2178
2179            mActivityManagerService.dumpDbInfo(fd, pw, args);
2180        }
2181    }
2182
2183    static class CpuBinder extends Binder {
2184        ActivityManagerService mActivityManagerService;
2185        CpuBinder(ActivityManagerService activityManagerService) {
2186            mActivityManagerService = activityManagerService;
2187        }
2188
2189        @Override
2190        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2191            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2192                    != PackageManager.PERMISSION_GRANTED) {
2193                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2194                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2195                        + " without permission " + android.Manifest.permission.DUMP);
2196                return;
2197            }
2198
2199            synchronized (mActivityManagerService.mProcessCpuTracker) {
2200                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2201                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2202                        SystemClock.uptimeMillis()));
2203            }
2204        }
2205    }
2206
2207    public static final class Lifecycle extends SystemService {
2208        private final ActivityManagerService mService;
2209
2210        public Lifecycle(Context context) {
2211            super(context);
2212            mService = new ActivityManagerService(context);
2213        }
2214
2215        @Override
2216        public void onStart() {
2217            mService.start();
2218        }
2219
2220        public ActivityManagerService getService() {
2221            return mService;
2222        }
2223    }
2224
2225    // Note: This method is invoked on the main thread but may need to attach various
2226    // handlers to other threads.  So take care to be explicit about the looper.
2227    public ActivityManagerService(Context systemContext) {
2228        mContext = systemContext;
2229        mFactoryTest = FactoryTest.getMode();
2230        mSystemThread = ActivityThread.currentActivityThread();
2231
2232        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2233
2234        mHandlerThread = new ServiceThread(TAG,
2235                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2236        mHandlerThread.start();
2237        mHandler = new MainHandler(mHandlerThread.getLooper());
2238
2239        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2240                "foreground", BROADCAST_FG_TIMEOUT, false);
2241        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2242                "background", BROADCAST_BG_TIMEOUT, true);
2243        mBroadcastQueues[0] = mFgBroadcastQueue;
2244        mBroadcastQueues[1] = mBgBroadcastQueue;
2245
2246        mServices = new ActiveServices(this);
2247        mProviderMap = new ProviderMap(this);
2248
2249        // TODO: Move creation of battery stats service outside of activity manager service.
2250        File dataDir = Environment.getDataDirectory();
2251        File systemDir = new File(dataDir, "system");
2252        systemDir.mkdirs();
2253        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2254        mBatteryStatsService.getActiveStatistics().readLocked();
2255        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2256        mOnBattery = DEBUG_POWER ? true
2257                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2258        mBatteryStatsService.getActiveStatistics().setCallback(this);
2259
2260        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2261
2262        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2263
2264        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2265
2266        // User 0 is the first and only user that runs at boot.
2267        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2268        mUserLru.add(Integer.valueOf(0));
2269        updateStartedUserArrayLocked();
2270
2271        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2272            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2273
2274        mConfiguration.setToDefaults();
2275        mConfiguration.setLocale(Locale.getDefault());
2276
2277        mConfigurationSeq = mConfiguration.seq = 1;
2278        mProcessCpuTracker.init();
2279
2280        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2281        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2282        mStackSupervisor = new ActivityStackSupervisor(this);
2283        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2284
2285        mProcessCpuThread = new Thread("CpuTracker") {
2286            @Override
2287            public void run() {
2288                while (true) {
2289                    try {
2290                        try {
2291                            synchronized(this) {
2292                                final long now = SystemClock.uptimeMillis();
2293                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2294                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2295                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2296                                //        + ", write delay=" + nextWriteDelay);
2297                                if (nextWriteDelay < nextCpuDelay) {
2298                                    nextCpuDelay = nextWriteDelay;
2299                                }
2300                                if (nextCpuDelay > 0) {
2301                                    mProcessCpuMutexFree.set(true);
2302                                    this.wait(nextCpuDelay);
2303                                }
2304                            }
2305                        } catch (InterruptedException e) {
2306                        }
2307                        updateCpuStatsNow();
2308                    } catch (Exception e) {
2309                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2310                    }
2311                }
2312            }
2313        };
2314
2315        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2316
2317        Watchdog.getInstance().addMonitor(this);
2318        Watchdog.getInstance().addThread(mHandler);
2319    }
2320
2321    public void setSystemServiceManager(SystemServiceManager mgr) {
2322        mSystemServiceManager = mgr;
2323    }
2324
2325    private void start() {
2326        Process.removeAllProcessGroups();
2327        mProcessCpuThread.start();
2328
2329        mBatteryStatsService.publish(mContext);
2330        mAppOpsService.publish(mContext);
2331        Slog.d("AppOps", "AppOpsService published");
2332        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2333    }
2334
2335    public void initPowerManagement() {
2336        mStackSupervisor.initPowerManagement();
2337        mBatteryStatsService.initPowerManagement();
2338    }
2339
2340    @Override
2341    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2342            throws RemoteException {
2343        if (code == SYSPROPS_TRANSACTION) {
2344            // We need to tell all apps about the system property change.
2345            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2346            synchronized(this) {
2347                final int NP = mProcessNames.getMap().size();
2348                for (int ip=0; ip<NP; ip++) {
2349                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2350                    final int NA = apps.size();
2351                    for (int ia=0; ia<NA; ia++) {
2352                        ProcessRecord app = apps.valueAt(ia);
2353                        if (app.thread != null) {
2354                            procs.add(app.thread.asBinder());
2355                        }
2356                    }
2357                }
2358            }
2359
2360            int N = procs.size();
2361            for (int i=0; i<N; i++) {
2362                Parcel data2 = Parcel.obtain();
2363                try {
2364                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2365                } catch (RemoteException e) {
2366                }
2367                data2.recycle();
2368            }
2369        }
2370        try {
2371            return super.onTransact(code, data, reply, flags);
2372        } catch (RuntimeException e) {
2373            // The activity manager only throws security exceptions, so let's
2374            // log all others.
2375            if (!(e instanceof SecurityException)) {
2376                Slog.wtf(TAG, "Activity Manager Crash", e);
2377            }
2378            throw e;
2379        }
2380    }
2381
2382    void updateCpuStats() {
2383        final long now = SystemClock.uptimeMillis();
2384        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2385            return;
2386        }
2387        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2388            synchronized (mProcessCpuThread) {
2389                mProcessCpuThread.notify();
2390            }
2391        }
2392    }
2393
2394    void updateCpuStatsNow() {
2395        synchronized (mProcessCpuTracker) {
2396            mProcessCpuMutexFree.set(false);
2397            final long now = SystemClock.uptimeMillis();
2398            boolean haveNewCpuStats = false;
2399
2400            if (MONITOR_CPU_USAGE &&
2401                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2402                mLastCpuTime.set(now);
2403                haveNewCpuStats = true;
2404                mProcessCpuTracker.update();
2405                //Slog.i(TAG, mProcessCpu.printCurrentState());
2406                //Slog.i(TAG, "Total CPU usage: "
2407                //        + mProcessCpu.getTotalCpuPercent() + "%");
2408
2409                // Slog the cpu usage if the property is set.
2410                if ("true".equals(SystemProperties.get("events.cpu"))) {
2411                    int user = mProcessCpuTracker.getLastUserTime();
2412                    int system = mProcessCpuTracker.getLastSystemTime();
2413                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2414                    int irq = mProcessCpuTracker.getLastIrqTime();
2415                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2416                    int idle = mProcessCpuTracker.getLastIdleTime();
2417
2418                    int total = user + system + iowait + irq + softIrq + idle;
2419                    if (total == 0) total = 1;
2420
2421                    EventLog.writeEvent(EventLogTags.CPU,
2422                            ((user+system+iowait+irq+softIrq) * 100) / total,
2423                            (user * 100) / total,
2424                            (system * 100) / total,
2425                            (iowait * 100) / total,
2426                            (irq * 100) / total,
2427                            (softIrq * 100) / total);
2428                }
2429            }
2430
2431            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2432            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2433            synchronized(bstats) {
2434                synchronized(mPidsSelfLocked) {
2435                    if (haveNewCpuStats) {
2436                        if (mOnBattery) {
2437                            int perc = bstats.startAddingCpuLocked();
2438                            int totalUTime = 0;
2439                            int totalSTime = 0;
2440                            final int N = mProcessCpuTracker.countStats();
2441                            for (int i=0; i<N; i++) {
2442                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2443                                if (!st.working) {
2444                                    continue;
2445                                }
2446                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2447                                int otherUTime = (st.rel_utime*perc)/100;
2448                                int otherSTime = (st.rel_stime*perc)/100;
2449                                totalUTime += otherUTime;
2450                                totalSTime += otherSTime;
2451                                if (pr != null) {
2452                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2453                                    if (ps == null || !ps.isActive()) {
2454                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2455                                                pr.info.uid, pr.processName);
2456                                    }
2457                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2458                                            st.rel_stime-otherSTime);
2459                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2460                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2461                                } else {
2462                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2463                                    if (ps == null || !ps.isActive()) {
2464                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2465                                                bstats.mapUid(st.uid), st.name);
2466                                    }
2467                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2468                                            st.rel_stime-otherSTime);
2469                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2470                                }
2471                            }
2472                            bstats.finishAddingCpuLocked(perc, totalUTime,
2473                                    totalSTime, cpuSpeedTimes);
2474                        }
2475                    }
2476                }
2477
2478                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2479                    mLastWriteTime = now;
2480                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2481                }
2482            }
2483        }
2484    }
2485
2486    @Override
2487    public void batteryNeedsCpuUpdate() {
2488        updateCpuStatsNow();
2489    }
2490
2491    @Override
2492    public void batteryPowerChanged(boolean onBattery) {
2493        // When plugging in, update the CPU stats first before changing
2494        // the plug state.
2495        updateCpuStatsNow();
2496        synchronized (this) {
2497            synchronized(mPidsSelfLocked) {
2498                mOnBattery = DEBUG_POWER ? true : onBattery;
2499            }
2500        }
2501    }
2502
2503    /**
2504     * Initialize the application bind args. These are passed to each
2505     * process when the bindApplication() IPC is sent to the process. They're
2506     * lazily setup to make sure the services are running when they're asked for.
2507     */
2508    private HashMap<String, IBinder> getCommonServicesLocked() {
2509        if (mAppBindArgs == null) {
2510            mAppBindArgs = new HashMap<String, IBinder>();
2511
2512            // Setup the application init args
2513            mAppBindArgs.put("package", ServiceManager.getService("package"));
2514            mAppBindArgs.put("window", ServiceManager.getService("window"));
2515            mAppBindArgs.put(Context.ALARM_SERVICE,
2516                    ServiceManager.getService(Context.ALARM_SERVICE));
2517        }
2518        return mAppBindArgs;
2519    }
2520
2521    final void setFocusedActivityLocked(ActivityRecord r) {
2522        if (mFocusedActivity != r) {
2523            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2524            mFocusedActivity = r;
2525            if (r.task != null && r.task.voiceInteractor != null) {
2526                startRunningVoiceLocked();
2527            } else {
2528                finishRunningVoiceLocked();
2529            }
2530            mStackSupervisor.setFocusedStack(r);
2531            if (r != null) {
2532                mWindowManager.setFocusedApp(r.appToken, true);
2533            }
2534            applyUpdateLockStateLocked(r);
2535        }
2536    }
2537
2538    final void clearFocusedActivity(ActivityRecord r) {
2539        if (mFocusedActivity == r) {
2540            mFocusedActivity = null;
2541        }
2542    }
2543
2544    @Override
2545    public void setFocusedStack(int stackId) {
2546        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2547        synchronized (ActivityManagerService.this) {
2548            ActivityStack stack = mStackSupervisor.getStack(stackId);
2549            if (stack != null) {
2550                ActivityRecord r = stack.topRunningActivityLocked(null);
2551                if (r != null) {
2552                    setFocusedActivityLocked(r);
2553                }
2554            }
2555        }
2556    }
2557
2558    @Override
2559    public void notifyActivityDrawn(IBinder token) {
2560        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2561        synchronized (this) {
2562            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2563            if (r != null) {
2564                r.task.stack.notifyActivityDrawnLocked(r);
2565            }
2566        }
2567    }
2568
2569    final void applyUpdateLockStateLocked(ActivityRecord r) {
2570        // Modifications to the UpdateLock state are done on our handler, outside
2571        // the activity manager's locks.  The new state is determined based on the
2572        // state *now* of the relevant activity record.  The object is passed to
2573        // the handler solely for logging detail, not to be consulted/modified.
2574        final boolean nextState = r != null && r.immersive;
2575        mHandler.sendMessage(
2576                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2577    }
2578
2579    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2580        Message msg = Message.obtain();
2581        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2582        msg.obj = r.task.askedCompatMode ? null : r;
2583        mHandler.sendMessage(msg);
2584    }
2585
2586    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2587            String what, Object obj, ProcessRecord srcApp) {
2588        app.lastActivityTime = now;
2589
2590        if (app.activities.size() > 0) {
2591            // Don't want to touch dependent processes that are hosting activities.
2592            return index;
2593        }
2594
2595        int lrui = mLruProcesses.lastIndexOf(app);
2596        if (lrui < 0) {
2597            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2598                    + what + " " + obj + " from " + srcApp);
2599            return index;
2600        }
2601
2602        if (lrui >= index) {
2603            // Don't want to cause this to move dependent processes *back* in the
2604            // list as if they were less frequently used.
2605            return index;
2606        }
2607
2608        if (lrui >= mLruProcessActivityStart) {
2609            // Don't want to touch dependent processes that are hosting activities.
2610            return index;
2611        }
2612
2613        mLruProcesses.remove(lrui);
2614        if (index > 0) {
2615            index--;
2616        }
2617        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2618                + " in LRU list: " + app);
2619        mLruProcesses.add(index, app);
2620        return index;
2621    }
2622
2623    final void removeLruProcessLocked(ProcessRecord app) {
2624        int lrui = mLruProcesses.lastIndexOf(app);
2625        if (lrui >= 0) {
2626            if (lrui <= mLruProcessActivityStart) {
2627                mLruProcessActivityStart--;
2628            }
2629            if (lrui <= mLruProcessServiceStart) {
2630                mLruProcessServiceStart--;
2631            }
2632            mLruProcesses.remove(lrui);
2633        }
2634    }
2635
2636    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2637            ProcessRecord client) {
2638        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2639                || app.treatLikeActivity;
2640        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2641        if (!activityChange && hasActivity) {
2642            // The process has activities, so we are only allowing activity-based adjustments
2643            // to move it.  It should be kept in the front of the list with other
2644            // processes that have activities, and we don't want those to change their
2645            // order except due to activity operations.
2646            return;
2647        }
2648
2649        mLruSeq++;
2650        final long now = SystemClock.uptimeMillis();
2651        app.lastActivityTime = now;
2652
2653        // First a quick reject: if the app is already at the position we will
2654        // put it, then there is nothing to do.
2655        if (hasActivity) {
2656            final int N = mLruProcesses.size();
2657            if (N > 0 && mLruProcesses.get(N-1) == app) {
2658                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2659                return;
2660            }
2661        } else {
2662            if (mLruProcessServiceStart > 0
2663                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2664                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2665                return;
2666            }
2667        }
2668
2669        int lrui = mLruProcesses.lastIndexOf(app);
2670
2671        if (app.persistent && lrui >= 0) {
2672            // We don't care about the position of persistent processes, as long as
2673            // they are in the list.
2674            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2675            return;
2676        }
2677
2678        /* In progress: compute new position first, so we can avoid doing work
2679           if the process is not actually going to move.  Not yet working.
2680        int addIndex;
2681        int nextIndex;
2682        boolean inActivity = false, inService = false;
2683        if (hasActivity) {
2684            // Process has activities, put it at the very tipsy-top.
2685            addIndex = mLruProcesses.size();
2686            nextIndex = mLruProcessServiceStart;
2687            inActivity = true;
2688        } else if (hasService) {
2689            // Process has services, put it at the top of the service list.
2690            addIndex = mLruProcessActivityStart;
2691            nextIndex = mLruProcessServiceStart;
2692            inActivity = true;
2693            inService = true;
2694        } else  {
2695            // Process not otherwise of interest, it goes to the top of the non-service area.
2696            addIndex = mLruProcessServiceStart;
2697            if (client != null) {
2698                int clientIndex = mLruProcesses.lastIndexOf(client);
2699                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2700                        + app);
2701                if (clientIndex >= 0 && addIndex > clientIndex) {
2702                    addIndex = clientIndex;
2703                }
2704            }
2705            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2706        }
2707
2708        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2709                + mLruProcessActivityStart + "): " + app);
2710        */
2711
2712        if (lrui >= 0) {
2713            if (lrui < mLruProcessActivityStart) {
2714                mLruProcessActivityStart--;
2715            }
2716            if (lrui < mLruProcessServiceStart) {
2717                mLruProcessServiceStart--;
2718            }
2719            /*
2720            if (addIndex > lrui) {
2721                addIndex--;
2722            }
2723            if (nextIndex > lrui) {
2724                nextIndex--;
2725            }
2726            */
2727            mLruProcesses.remove(lrui);
2728        }
2729
2730        /*
2731        mLruProcesses.add(addIndex, app);
2732        if (inActivity) {
2733            mLruProcessActivityStart++;
2734        }
2735        if (inService) {
2736            mLruProcessActivityStart++;
2737        }
2738        */
2739
2740        int nextIndex;
2741        if (hasActivity) {
2742            final int N = mLruProcesses.size();
2743            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2744                // Process doesn't have activities, but has clients with
2745                // activities...  move it up, but one below the top (the top
2746                // should always have a real activity).
2747                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2748                mLruProcesses.add(N-1, app);
2749                // To keep it from spamming the LRU list (by making a bunch of clients),
2750                // we will push down any other entries owned by the app.
2751                final int uid = app.info.uid;
2752                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2753                    ProcessRecord subProc = mLruProcesses.get(i);
2754                    if (subProc.info.uid == uid) {
2755                        // We want to push this one down the list.  If the process after
2756                        // it is for the same uid, however, don't do so, because we don't
2757                        // want them internally to be re-ordered.
2758                        if (mLruProcesses.get(i-1).info.uid != uid) {
2759                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2760                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2761                            ProcessRecord tmp = mLruProcesses.get(i);
2762                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2763                            mLruProcesses.set(i-1, tmp);
2764                            i--;
2765                        }
2766                    } else {
2767                        // A gap, we can stop here.
2768                        break;
2769                    }
2770                }
2771            } else {
2772                // Process has activities, put it at the very tipsy-top.
2773                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2774                mLruProcesses.add(app);
2775            }
2776            nextIndex = mLruProcessServiceStart;
2777        } else if (hasService) {
2778            // Process has services, put it at the top of the service list.
2779            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2780            mLruProcesses.add(mLruProcessActivityStart, app);
2781            nextIndex = mLruProcessServiceStart;
2782            mLruProcessActivityStart++;
2783        } else  {
2784            // Process not otherwise of interest, it goes to the top of the non-service area.
2785            int index = mLruProcessServiceStart;
2786            if (client != null) {
2787                // If there is a client, don't allow the process to be moved up higher
2788                // in the list than that client.
2789                int clientIndex = mLruProcesses.lastIndexOf(client);
2790                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2791                        + " when updating " + app);
2792                if (clientIndex <= lrui) {
2793                    // Don't allow the client index restriction to push it down farther in the
2794                    // list than it already is.
2795                    clientIndex = lrui;
2796                }
2797                if (clientIndex >= 0 && index > clientIndex) {
2798                    index = clientIndex;
2799                }
2800            }
2801            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2802            mLruProcesses.add(index, app);
2803            nextIndex = index-1;
2804            mLruProcessActivityStart++;
2805            mLruProcessServiceStart++;
2806        }
2807
2808        // If the app is currently using a content provider or service,
2809        // bump those processes as well.
2810        for (int j=app.connections.size()-1; j>=0; j--) {
2811            ConnectionRecord cr = app.connections.valueAt(j);
2812            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2813                    && cr.binding.service.app != null
2814                    && cr.binding.service.app.lruSeq != mLruSeq
2815                    && !cr.binding.service.app.persistent) {
2816                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2817                        "service connection", cr, app);
2818            }
2819        }
2820        for (int j=app.conProviders.size()-1; j>=0; j--) {
2821            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2822            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2823                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2824                        "provider reference", cpr, app);
2825            }
2826        }
2827    }
2828
2829    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2830        if (uid == Process.SYSTEM_UID) {
2831            // The system gets to run in any process.  If there are multiple
2832            // processes with the same uid, just pick the first (this
2833            // should never happen).
2834            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2835            if (procs == null) return null;
2836            final int N = procs.size();
2837            for (int i = 0; i < N; i++) {
2838                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2839            }
2840        }
2841        ProcessRecord proc = mProcessNames.get(processName, uid);
2842        if (false && proc != null && !keepIfLarge
2843                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2844                && proc.lastCachedPss >= 4000) {
2845            // Turn this condition on to cause killing to happen regularly, for testing.
2846            if (proc.baseProcessTracker != null) {
2847                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2848            }
2849            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2850        } else if (proc != null && !keepIfLarge
2851                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2852                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2853            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2854            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2855                if (proc.baseProcessTracker != null) {
2856                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2857                }
2858                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2859            }
2860        }
2861        return proc;
2862    }
2863
2864    void ensurePackageDexOpt(String packageName) {
2865        IPackageManager pm = AppGlobals.getPackageManager();
2866        try {
2867            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2868                mDidDexOpt = true;
2869            }
2870        } catch (RemoteException e) {
2871        }
2872    }
2873
2874    boolean isNextTransitionForward() {
2875        int transit = mWindowManager.getPendingAppTransition();
2876        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2877                || transit == AppTransition.TRANSIT_TASK_OPEN
2878                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2879    }
2880
2881    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2882            String processName, String abiOverride, int uid, Runnable crashHandler) {
2883        synchronized(this) {
2884            ApplicationInfo info = new ApplicationInfo();
2885            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2886            // For isolated processes, the former contains the parent's uid and the latter the
2887            // actual uid of the isolated process.
2888            // In the special case introduced by this method (which is, starting an isolated
2889            // process directly from the SystemServer without an actual parent app process) the
2890            // closest thing to a parent's uid is SYSTEM_UID.
2891            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2892            // the |isolated| logic in the ProcessRecord constructor.
2893            info.uid = Process.SYSTEM_UID;
2894            info.processName = processName;
2895            info.className = entryPoint;
2896            info.packageName = "android";
2897            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2898                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2899                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2900                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2901                    crashHandler);
2902            return proc != null ? proc.pid : 0;
2903        }
2904    }
2905
2906    final ProcessRecord startProcessLocked(String processName,
2907            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2908            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2909            boolean isolated, boolean keepIfLarge) {
2910        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2911                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2912                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2913                null /* crashHandler */);
2914    }
2915
2916    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2917            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2918            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2919            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2920        long startTime = SystemClock.elapsedRealtime();
2921        ProcessRecord app;
2922        if (!isolated) {
2923            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2924            checkTime(startTime, "startProcess: after getProcessRecord");
2925        } else {
2926            // If this is an isolated process, it can't re-use an existing process.
2927            app = null;
2928        }
2929        // We don't have to do anything more if:
2930        // (1) There is an existing application record; and
2931        // (2) The caller doesn't think it is dead, OR there is no thread
2932        //     object attached to it so we know it couldn't have crashed; and
2933        // (3) There is a pid assigned to it, so it is either starting or
2934        //     already running.
2935        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2936                + " app=" + app + " knownToBeDead=" + knownToBeDead
2937                + " thread=" + (app != null ? app.thread : null)
2938                + " pid=" + (app != null ? app.pid : -1));
2939        if (app != null && app.pid > 0) {
2940            if (!knownToBeDead || app.thread == null) {
2941                // We already have the app running, or are waiting for it to
2942                // come up (we have a pid but not yet its thread), so keep it.
2943                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2944                // If this is a new package in the process, add the package to the list
2945                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2946                checkTime(startTime, "startProcess: done, added package to proc");
2947                return app;
2948            }
2949
2950            // An application record is attached to a previous process,
2951            // clean it up now.
2952            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2953            checkTime(startTime, "startProcess: bad proc running, killing");
2954            Process.killProcessGroup(app.info.uid, app.pid);
2955            handleAppDiedLocked(app, true, true);
2956            checkTime(startTime, "startProcess: done killing old proc");
2957        }
2958
2959        String hostingNameStr = hostingName != null
2960                ? hostingName.flattenToShortString() : null;
2961
2962        if (!isolated) {
2963            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2964                // If we are in the background, then check to see if this process
2965                // is bad.  If so, we will just silently fail.
2966                if (mBadProcesses.get(info.processName, info.uid) != null) {
2967                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2968                            + "/" + info.processName);
2969                    return null;
2970                }
2971            } else {
2972                // When the user is explicitly starting a process, then clear its
2973                // crash count so that we won't make it bad until they see at
2974                // least one crash dialog again, and make the process good again
2975                // if it had been bad.
2976                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2977                        + "/" + info.processName);
2978                mProcessCrashTimes.remove(info.processName, info.uid);
2979                if (mBadProcesses.get(info.processName, info.uid) != null) {
2980                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2981                            UserHandle.getUserId(info.uid), info.uid,
2982                            info.processName);
2983                    mBadProcesses.remove(info.processName, info.uid);
2984                    if (app != null) {
2985                        app.bad = false;
2986                    }
2987                }
2988            }
2989        }
2990
2991        if (app == null) {
2992            checkTime(startTime, "startProcess: creating new process record");
2993            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2994            app.crashHandler = crashHandler;
2995            if (app == null) {
2996                Slog.w(TAG, "Failed making new process record for "
2997                        + processName + "/" + info.uid + " isolated=" + isolated);
2998                return null;
2999            }
3000            mProcessNames.put(processName, app.uid, app);
3001            if (isolated) {
3002                mIsolatedProcesses.put(app.uid, app);
3003            }
3004            checkTime(startTime, "startProcess: done creating new process record");
3005        } else {
3006            // If this is a new package in the process, add the package to the list
3007            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3008            checkTime(startTime, "startProcess: added package to existing proc");
3009        }
3010
3011        // If the system is not ready yet, then hold off on starting this
3012        // process until it is.
3013        if (!mProcessesReady
3014                && !isAllowedWhileBooting(info)
3015                && !allowWhileBooting) {
3016            if (!mProcessesOnHold.contains(app)) {
3017                mProcessesOnHold.add(app);
3018            }
3019            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3020            checkTime(startTime, "startProcess: returning with proc on hold");
3021            return app;
3022        }
3023
3024        checkTime(startTime, "startProcess: stepping in to startProcess");
3025        startProcessLocked(
3026                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3027        checkTime(startTime, "startProcess: done starting proc!");
3028        return (app.pid != 0) ? app : null;
3029    }
3030
3031    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3032        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3033    }
3034
3035    private final void startProcessLocked(ProcessRecord app,
3036            String hostingType, String hostingNameStr) {
3037        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3038                null /* entryPoint */, null /* entryPointArgs */);
3039    }
3040
3041    private final void startProcessLocked(ProcessRecord app, String hostingType,
3042            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3043        long startTime = SystemClock.elapsedRealtime();
3044        if (app.pid > 0 && app.pid != MY_PID) {
3045            checkTime(startTime, "startProcess: removing from pids map");
3046            synchronized (mPidsSelfLocked) {
3047                mPidsSelfLocked.remove(app.pid);
3048                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3049            }
3050            checkTime(startTime, "startProcess: done removing from pids map");
3051            app.setPid(0);
3052        }
3053
3054        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3055                "startProcessLocked removing on hold: " + app);
3056        mProcessesOnHold.remove(app);
3057
3058        checkTime(startTime, "startProcess: starting to update cpu stats");
3059        updateCpuStats();
3060        checkTime(startTime, "startProcess: done updating cpu stats");
3061
3062        try {
3063            int uid = app.uid;
3064
3065            int[] gids = null;
3066            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3067            if (!app.isolated) {
3068                int[] permGids = null;
3069                try {
3070                    checkTime(startTime, "startProcess: getting gids from package manager");
3071                    final PackageManager pm = mContext.getPackageManager();
3072                    permGids = pm.getPackageGids(app.info.packageName);
3073
3074                    if (Environment.isExternalStorageEmulated()) {
3075                        checkTime(startTime, "startProcess: checking external storage perm");
3076                        if (pm.checkPermission(
3077                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3078                                app.info.packageName) == PERMISSION_GRANTED) {
3079                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3080                        } else {
3081                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3082                        }
3083                    }
3084                } catch (PackageManager.NameNotFoundException e) {
3085                    Slog.w(TAG, "Unable to retrieve gids", e);
3086                }
3087
3088                /*
3089                 * Add shared application and profile GIDs so applications can share some
3090                 * resources like shared libraries and access user-wide resources
3091                 */
3092                if (permGids == null) {
3093                    gids = new int[2];
3094                } else {
3095                    gids = new int[permGids.length + 2];
3096                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3097                }
3098                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3099                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3100            }
3101            checkTime(startTime, "startProcess: building args");
3102            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3103                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3104                        && mTopComponent != null
3105                        && app.processName.equals(mTopComponent.getPackageName())) {
3106                    uid = 0;
3107                }
3108                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3109                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3110                    uid = 0;
3111                }
3112            }
3113            int debugFlags = 0;
3114            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3115                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3116                // Also turn on CheckJNI for debuggable apps. It's quite
3117                // awkward to turn on otherwise.
3118                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3119            }
3120            // Run the app in safe mode if its manifest requests so or the
3121            // system is booted in safe mode.
3122            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3123                mSafeMode == true) {
3124                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3125            }
3126            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3127                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3128            }
3129            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3130                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3131            }
3132            if ("1".equals(SystemProperties.get("debug.assert"))) {
3133                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3134            }
3135
3136            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3137            if (requiredAbi == null) {
3138                requiredAbi = Build.SUPPORTED_ABIS[0];
3139            }
3140
3141            String instructionSet = null;
3142            if (app.info.primaryCpuAbi != null) {
3143                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3144            }
3145
3146            // Start the process.  It will either succeed and return a result containing
3147            // the PID of the new process, or else throw a RuntimeException.
3148            boolean isActivityProcess = (entryPoint == null);
3149            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3150            checkTime(startTime, "startProcess: asking zygote to start proc");
3151            Process.ProcessStartResult startResult = Process.start(entryPoint,
3152                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3153                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3154                    entryPointArgs);
3155            checkTime(startTime, "startProcess: returned from zygote!");
3156
3157            if (app.isolated) {
3158                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3159            }
3160            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3161            checkTime(startTime, "startProcess: done updating battery stats");
3162
3163            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3164                    UserHandle.getUserId(uid), startResult.pid, uid,
3165                    app.processName, hostingType,
3166                    hostingNameStr != null ? hostingNameStr : "");
3167
3168            if (app.persistent) {
3169                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3170            }
3171
3172            checkTime(startTime, "startProcess: building log message");
3173            StringBuilder buf = mStringBuilder;
3174            buf.setLength(0);
3175            buf.append("Start proc ");
3176            buf.append(app.processName);
3177            if (!isActivityProcess) {
3178                buf.append(" [");
3179                buf.append(entryPoint);
3180                buf.append("]");
3181            }
3182            buf.append(" for ");
3183            buf.append(hostingType);
3184            if (hostingNameStr != null) {
3185                buf.append(" ");
3186                buf.append(hostingNameStr);
3187            }
3188            buf.append(": pid=");
3189            buf.append(startResult.pid);
3190            buf.append(" uid=");
3191            buf.append(uid);
3192            buf.append(" gids={");
3193            if (gids != null) {
3194                for (int gi=0; gi<gids.length; gi++) {
3195                    if (gi != 0) buf.append(", ");
3196                    buf.append(gids[gi]);
3197
3198                }
3199            }
3200            buf.append("}");
3201            if (requiredAbi != null) {
3202                buf.append(" abi=");
3203                buf.append(requiredAbi);
3204            }
3205            Slog.i(TAG, buf.toString());
3206            app.setPid(startResult.pid);
3207            app.usingWrapper = startResult.usingWrapper;
3208            app.removed = false;
3209            app.killedByAm = false;
3210            checkTime(startTime, "startProcess: starting to update pids map");
3211            synchronized (mPidsSelfLocked) {
3212                this.mPidsSelfLocked.put(startResult.pid, app);
3213                if (isActivityProcess) {
3214                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3215                    msg.obj = app;
3216                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3217                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3218                }
3219            }
3220            checkTime(startTime, "startProcess: done updating pids map");
3221        } catch (RuntimeException e) {
3222            // XXX do better error recovery.
3223            app.setPid(0);
3224            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3225            if (app.isolated) {
3226                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3227            }
3228            Slog.e(TAG, "Failure starting process " + app.processName, e);
3229        }
3230    }
3231
3232    void updateUsageStats(ActivityRecord component, boolean resumed) {
3233        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3234        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3235        if (resumed) {
3236            if (mUsageStatsService != null) {
3237                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3238                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3239            }
3240            synchronized (stats) {
3241                stats.noteActivityResumedLocked(component.app.uid);
3242            }
3243        } else {
3244            if (mUsageStatsService != null) {
3245                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3246                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3247            }
3248            synchronized (stats) {
3249                stats.noteActivityPausedLocked(component.app.uid);
3250            }
3251        }
3252    }
3253
3254    Intent getHomeIntent() {
3255        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3256        intent.setComponent(mTopComponent);
3257        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3258            intent.addCategory(Intent.CATEGORY_HOME);
3259        }
3260        return intent;
3261    }
3262
3263    boolean startHomeActivityLocked(int userId) {
3264        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3265                && mTopAction == null) {
3266            // We are running in factory test mode, but unable to find
3267            // the factory test app, so just sit around displaying the
3268            // error message and don't try to start anything.
3269            return false;
3270        }
3271        Intent intent = getHomeIntent();
3272        ActivityInfo aInfo =
3273            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3274        if (aInfo != null) {
3275            intent.setComponent(new ComponentName(
3276                    aInfo.applicationInfo.packageName, aInfo.name));
3277            // Don't do this if the home app is currently being
3278            // instrumented.
3279            aInfo = new ActivityInfo(aInfo);
3280            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3281            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3282                    aInfo.applicationInfo.uid, true);
3283            if (app == null || app.instrumentationClass == null) {
3284                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3285                mStackSupervisor.startHomeActivity(intent, aInfo);
3286            }
3287        }
3288
3289        return true;
3290    }
3291
3292    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3293        ActivityInfo ai = null;
3294        ComponentName comp = intent.getComponent();
3295        try {
3296            if (comp != null) {
3297                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3298            } else {
3299                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3300                        intent,
3301                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3302                            flags, userId);
3303
3304                if (info != null) {
3305                    ai = info.activityInfo;
3306                }
3307            }
3308        } catch (RemoteException e) {
3309            // ignore
3310        }
3311
3312        return ai;
3313    }
3314
3315    /**
3316     * Starts the "new version setup screen" if appropriate.
3317     */
3318    void startSetupActivityLocked() {
3319        // Only do this once per boot.
3320        if (mCheckedForSetup) {
3321            return;
3322        }
3323
3324        // We will show this screen if the current one is a different
3325        // version than the last one shown, and we are not running in
3326        // low-level factory test mode.
3327        final ContentResolver resolver = mContext.getContentResolver();
3328        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3329                Settings.Global.getInt(resolver,
3330                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3331            mCheckedForSetup = true;
3332
3333            // See if we should be showing the platform update setup UI.
3334            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3335            List<ResolveInfo> ris = mContext.getPackageManager()
3336                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3337
3338            // We don't allow third party apps to replace this.
3339            ResolveInfo ri = null;
3340            for (int i=0; ris != null && i<ris.size(); i++) {
3341                if ((ris.get(i).activityInfo.applicationInfo.flags
3342                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3343                    ri = ris.get(i);
3344                    break;
3345                }
3346            }
3347
3348            if (ri != null) {
3349                String vers = ri.activityInfo.metaData != null
3350                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3351                        : null;
3352                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3353                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3354                            Intent.METADATA_SETUP_VERSION);
3355                }
3356                String lastVers = Settings.Secure.getString(
3357                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3358                if (vers != null && !vers.equals(lastVers)) {
3359                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3360                    intent.setComponent(new ComponentName(
3361                            ri.activityInfo.packageName, ri.activityInfo.name));
3362                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3363                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3364                            null);
3365                }
3366            }
3367        }
3368    }
3369
3370    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3371        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3372    }
3373
3374    void enforceNotIsolatedCaller(String caller) {
3375        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3376            throw new SecurityException("Isolated process not allowed to call " + caller);
3377        }
3378    }
3379
3380    void enforceShellRestriction(String restriction, int userHandle) {
3381        if (Binder.getCallingUid() == Process.SHELL_UID) {
3382            if (userHandle < 0
3383                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3384                throw new SecurityException("Shell does not have permission to access user "
3385                        + userHandle);
3386            }
3387        }
3388    }
3389
3390    @Override
3391    public int getFrontActivityScreenCompatMode() {
3392        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3393        synchronized (this) {
3394            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3395        }
3396    }
3397
3398    @Override
3399    public void setFrontActivityScreenCompatMode(int mode) {
3400        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3401                "setFrontActivityScreenCompatMode");
3402        synchronized (this) {
3403            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3404        }
3405    }
3406
3407    @Override
3408    public int getPackageScreenCompatMode(String packageName) {
3409        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3410        synchronized (this) {
3411            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3412        }
3413    }
3414
3415    @Override
3416    public void setPackageScreenCompatMode(String packageName, int mode) {
3417        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3418                "setPackageScreenCompatMode");
3419        synchronized (this) {
3420            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3421        }
3422    }
3423
3424    @Override
3425    public boolean getPackageAskScreenCompat(String packageName) {
3426        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3427        synchronized (this) {
3428            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3429        }
3430    }
3431
3432    @Override
3433    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3434        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3435                "setPackageAskScreenCompat");
3436        synchronized (this) {
3437            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3438        }
3439    }
3440
3441    private void dispatchProcessesChanged() {
3442        int N;
3443        synchronized (this) {
3444            N = mPendingProcessChanges.size();
3445            if (mActiveProcessChanges.length < N) {
3446                mActiveProcessChanges = new ProcessChangeItem[N];
3447            }
3448            mPendingProcessChanges.toArray(mActiveProcessChanges);
3449            mAvailProcessChanges.addAll(mPendingProcessChanges);
3450            mPendingProcessChanges.clear();
3451            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3452        }
3453
3454        int i = mProcessObservers.beginBroadcast();
3455        while (i > 0) {
3456            i--;
3457            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3458            if (observer != null) {
3459                try {
3460                    for (int j=0; j<N; j++) {
3461                        ProcessChangeItem item = mActiveProcessChanges[j];
3462                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3463                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3464                                    + item.pid + " uid=" + item.uid + ": "
3465                                    + item.foregroundActivities);
3466                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3467                                    item.foregroundActivities);
3468                        }
3469                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3470                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3471                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3472                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3473                        }
3474                    }
3475                } catch (RemoteException e) {
3476                }
3477            }
3478        }
3479        mProcessObservers.finishBroadcast();
3480    }
3481
3482    private void dispatchProcessDied(int pid, int uid) {
3483        int i = mProcessObservers.beginBroadcast();
3484        while (i > 0) {
3485            i--;
3486            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3487            if (observer != null) {
3488                try {
3489                    observer.onProcessDied(pid, uid);
3490                } catch (RemoteException e) {
3491                }
3492            }
3493        }
3494        mProcessObservers.finishBroadcast();
3495    }
3496
3497    @Override
3498    public final int startActivity(IApplicationThread caller, String callingPackage,
3499            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3500            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3501        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3502            resultWho, requestCode, startFlags, profilerInfo, options,
3503            UserHandle.getCallingUserId());
3504    }
3505
3506    @Override
3507    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3508            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3509            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3510        enforceNotIsolatedCaller("startActivity");
3511        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3512                false, ALLOW_FULL_ONLY, "startActivity", null);
3513        // TODO: Switch to user app stacks here.
3514        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3515                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3516                profilerInfo, null, null, options, userId, null, null);
3517    }
3518
3519    @Override
3520    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3521            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3522            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3523
3524        // This is very dangerous -- it allows you to perform a start activity (including
3525        // permission grants) as any app that may launch one of your own activities.  So
3526        // we will only allow this to be done from activities that are part of the core framework,
3527        // and then only when they are running as the system.
3528        final ActivityRecord sourceRecord;
3529        final int targetUid;
3530        final String targetPackage;
3531        synchronized (this) {
3532            if (resultTo == null) {
3533                throw new SecurityException("Must be called from an activity");
3534            }
3535            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3536            if (sourceRecord == null) {
3537                throw new SecurityException("Called with bad activity token: " + resultTo);
3538            }
3539            if (!sourceRecord.info.packageName.equals("android")) {
3540                throw new SecurityException(
3541                        "Must be called from an activity that is declared in the android package");
3542            }
3543            if (sourceRecord.app == null) {
3544                throw new SecurityException("Called without a process attached to activity");
3545            }
3546            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3547                // This is still okay, as long as this activity is running under the
3548                // uid of the original calling activity.
3549                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3550                    throw new SecurityException(
3551                            "Calling activity in uid " + sourceRecord.app.uid
3552                                    + " must be system uid or original calling uid "
3553                                    + sourceRecord.launchedFromUid);
3554                }
3555            }
3556            targetUid = sourceRecord.launchedFromUid;
3557            targetPackage = sourceRecord.launchedFromPackage;
3558        }
3559
3560        // TODO: Switch to user app stacks here.
3561        try {
3562            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3563                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3564                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3565            return ret;
3566        } catch (SecurityException e) {
3567            // XXX need to figure out how to propagate to original app.
3568            // A SecurityException here is generally actually a fault of the original
3569            // calling activity (such as a fairly granting permissions), so propagate it
3570            // back to them.
3571            /*
3572            StringBuilder msg = new StringBuilder();
3573            msg.append("While launching");
3574            msg.append(intent.toString());
3575            msg.append(": ");
3576            msg.append(e.getMessage());
3577            */
3578            throw e;
3579        }
3580    }
3581
3582    @Override
3583    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3584            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3585            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3586        enforceNotIsolatedCaller("startActivityAndWait");
3587        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3588                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3589        WaitResult res = new WaitResult();
3590        // TODO: Switch to user app stacks here.
3591        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3592                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3593                options, userId, null, null);
3594        return res;
3595    }
3596
3597    @Override
3598    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3599            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3600            int startFlags, Configuration config, Bundle options, int userId) {
3601        enforceNotIsolatedCaller("startActivityWithConfig");
3602        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3603                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3604        // TODO: Switch to user app stacks here.
3605        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3606                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3607                null, null, config, options, userId, null, null);
3608        return ret;
3609    }
3610
3611    @Override
3612    public int startActivityIntentSender(IApplicationThread caller,
3613            IntentSender intent, Intent fillInIntent, String resolvedType,
3614            IBinder resultTo, String resultWho, int requestCode,
3615            int flagsMask, int flagsValues, Bundle options) {
3616        enforceNotIsolatedCaller("startActivityIntentSender");
3617        // Refuse possible leaked file descriptors
3618        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3619            throw new IllegalArgumentException("File descriptors passed in Intent");
3620        }
3621
3622        IIntentSender sender = intent.getTarget();
3623        if (!(sender instanceof PendingIntentRecord)) {
3624            throw new IllegalArgumentException("Bad PendingIntent object");
3625        }
3626
3627        PendingIntentRecord pir = (PendingIntentRecord)sender;
3628
3629        synchronized (this) {
3630            // If this is coming from the currently resumed activity, it is
3631            // effectively saying that app switches are allowed at this point.
3632            final ActivityStack stack = getFocusedStack();
3633            if (stack.mResumedActivity != null &&
3634                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3635                mAppSwitchesAllowedTime = 0;
3636            }
3637        }
3638        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3639                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3640        return ret;
3641    }
3642
3643    @Override
3644    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3645            Intent intent, String resolvedType, IVoiceInteractionSession session,
3646            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3647            Bundle options, int userId) {
3648        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3649                != PackageManager.PERMISSION_GRANTED) {
3650            String msg = "Permission Denial: startVoiceActivity() from pid="
3651                    + Binder.getCallingPid()
3652                    + ", uid=" + Binder.getCallingUid()
3653                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3654            Slog.w(TAG, msg);
3655            throw new SecurityException(msg);
3656        }
3657        if (session == null || interactor == null) {
3658            throw new NullPointerException("null session or interactor");
3659        }
3660        userId = handleIncomingUser(callingPid, callingUid, userId,
3661                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3662        // TODO: Switch to user app stacks here.
3663        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3664                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3665                null, options, userId, null, null);
3666    }
3667
3668    @Override
3669    public boolean startNextMatchingActivity(IBinder callingActivity,
3670            Intent intent, Bundle options) {
3671        // Refuse possible leaked file descriptors
3672        if (intent != null && intent.hasFileDescriptors() == true) {
3673            throw new IllegalArgumentException("File descriptors passed in Intent");
3674        }
3675
3676        synchronized (this) {
3677            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3678            if (r == null) {
3679                ActivityOptions.abort(options);
3680                return false;
3681            }
3682            if (r.app == null || r.app.thread == null) {
3683                // The caller is not running...  d'oh!
3684                ActivityOptions.abort(options);
3685                return false;
3686            }
3687            intent = new Intent(intent);
3688            // The caller is not allowed to change the data.
3689            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3690            // And we are resetting to find the next component...
3691            intent.setComponent(null);
3692
3693            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3694
3695            ActivityInfo aInfo = null;
3696            try {
3697                List<ResolveInfo> resolves =
3698                    AppGlobals.getPackageManager().queryIntentActivities(
3699                            intent, r.resolvedType,
3700                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3701                            UserHandle.getCallingUserId());
3702
3703                // Look for the original activity in the list...
3704                final int N = resolves != null ? resolves.size() : 0;
3705                for (int i=0; i<N; i++) {
3706                    ResolveInfo rInfo = resolves.get(i);
3707                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3708                            && rInfo.activityInfo.name.equals(r.info.name)) {
3709                        // We found the current one...  the next matching is
3710                        // after it.
3711                        i++;
3712                        if (i<N) {
3713                            aInfo = resolves.get(i).activityInfo;
3714                        }
3715                        if (debug) {
3716                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3717                                    + "/" + r.info.name);
3718                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3719                                    + "/" + aInfo.name);
3720                        }
3721                        break;
3722                    }
3723                }
3724            } catch (RemoteException e) {
3725            }
3726
3727            if (aInfo == null) {
3728                // Nobody who is next!
3729                ActivityOptions.abort(options);
3730                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3731                return false;
3732            }
3733
3734            intent.setComponent(new ComponentName(
3735                    aInfo.applicationInfo.packageName, aInfo.name));
3736            intent.setFlags(intent.getFlags()&~(
3737                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3738                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3739                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3740                    Intent.FLAG_ACTIVITY_NEW_TASK));
3741
3742            // Okay now we need to start the new activity, replacing the
3743            // currently running activity.  This is a little tricky because
3744            // we want to start the new one as if the current one is finished,
3745            // but not finish the current one first so that there is no flicker.
3746            // And thus...
3747            final boolean wasFinishing = r.finishing;
3748            r.finishing = true;
3749
3750            // Propagate reply information over to the new activity.
3751            final ActivityRecord resultTo = r.resultTo;
3752            final String resultWho = r.resultWho;
3753            final int requestCode = r.requestCode;
3754            r.resultTo = null;
3755            if (resultTo != null) {
3756                resultTo.removeResultsLocked(r, resultWho, requestCode);
3757            }
3758
3759            final long origId = Binder.clearCallingIdentity();
3760            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3761                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3762                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3763                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3764            Binder.restoreCallingIdentity(origId);
3765
3766            r.finishing = wasFinishing;
3767            if (res != ActivityManager.START_SUCCESS) {
3768                return false;
3769            }
3770            return true;
3771        }
3772    }
3773
3774    @Override
3775    public final int startActivityFromRecents(int taskId, Bundle options) {
3776        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3777            String msg = "Permission Denial: startActivityFromRecents called without " +
3778                    START_TASKS_FROM_RECENTS;
3779            Slog.w(TAG, msg);
3780            throw new SecurityException(msg);
3781        }
3782        return startActivityFromRecentsInner(taskId, options);
3783    }
3784
3785    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3786        final TaskRecord task;
3787        final int callingUid;
3788        final String callingPackage;
3789        final Intent intent;
3790        final int userId;
3791        synchronized (this) {
3792            task = recentTaskForIdLocked(taskId);
3793            if (task == null) {
3794                throw new IllegalArgumentException("Task " + taskId + " not found.");
3795            }
3796            callingUid = task.mCallingUid;
3797            callingPackage = task.mCallingPackage;
3798            intent = task.intent;
3799            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3800            userId = task.userId;
3801        }
3802        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3803                options, userId, null, task);
3804    }
3805
3806    final int startActivityInPackage(int uid, String callingPackage,
3807            Intent intent, String resolvedType, IBinder resultTo,
3808            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3809            IActivityContainer container, TaskRecord inTask) {
3810
3811        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3812                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3813
3814        // TODO: Switch to user app stacks here.
3815        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3816                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3817                null, null, null, options, userId, container, inTask);
3818        return ret;
3819    }
3820
3821    @Override
3822    public final int startActivities(IApplicationThread caller, String callingPackage,
3823            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3824            int userId) {
3825        enforceNotIsolatedCaller("startActivities");
3826        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3827                false, ALLOW_FULL_ONLY, "startActivity", null);
3828        // TODO: Switch to user app stacks here.
3829        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3830                resolvedTypes, resultTo, options, userId);
3831        return ret;
3832    }
3833
3834    final int startActivitiesInPackage(int uid, String callingPackage,
3835            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3836            Bundle options, int userId) {
3837
3838        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3839                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3840        // TODO: Switch to user app stacks here.
3841        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3842                resultTo, options, userId);
3843        return ret;
3844    }
3845
3846    //explicitly remove thd old information in mRecentTasks when removing existing user.
3847    private void removeRecentTasksForUserLocked(int userId) {
3848        if(userId <= 0) {
3849            Slog.i(TAG, "Can't remove recent task on user " + userId);
3850            return;
3851        }
3852
3853        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3854            TaskRecord tr = mRecentTasks.get(i);
3855            if (tr.userId == userId) {
3856                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3857                        + " when finishing user" + userId);
3858                mRecentTasks.remove(i);
3859                tr.removedFromRecents(mTaskPersister);
3860            }
3861        }
3862
3863        // Remove tasks from persistent storage.
3864        mTaskPersister.wakeup(null, true);
3865    }
3866
3867    // Sort by taskId
3868    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3869        @Override
3870        public int compare(TaskRecord lhs, TaskRecord rhs) {
3871            return rhs.taskId - lhs.taskId;
3872        }
3873    };
3874
3875    // Extract the affiliates of the chain containing mRecentTasks[start].
3876    private int processNextAffiliateChain(int start) {
3877        final TaskRecord startTask = mRecentTasks.get(start);
3878        final int affiliateId = startTask.mAffiliatedTaskId;
3879
3880        // Quick identification of isolated tasks. I.e. those not launched behind.
3881        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3882                startTask.mNextAffiliate == null) {
3883            // There is still a slim chance that there are other tasks that point to this task
3884            // and that the chain is so messed up that this task no longer points to them but
3885            // the gain of this optimization outweighs the risk.
3886            startTask.inRecents = true;
3887            return start + 1;
3888        }
3889
3890        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3891        mTmpRecents.clear();
3892        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3893            final TaskRecord task = mRecentTasks.get(i);
3894            if (task.mAffiliatedTaskId == affiliateId) {
3895                mRecentTasks.remove(i);
3896                mTmpRecents.add(task);
3897            }
3898        }
3899
3900        // Sort them all by taskId. That is the order they were create in and that order will
3901        // always be correct.
3902        Collections.sort(mTmpRecents, mTaskRecordComparator);
3903
3904        // Go through and fix up the linked list.
3905        // The first one is the end of the chain and has no next.
3906        final TaskRecord first = mTmpRecents.get(0);
3907        first.inRecents = true;
3908        if (first.mNextAffiliate != null) {
3909            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3910            first.setNextAffiliate(null);
3911            mTaskPersister.wakeup(first, false);
3912        }
3913        // Everything in the middle is doubly linked from next to prev.
3914        final int tmpSize = mTmpRecents.size();
3915        for (int i = 0; i < tmpSize - 1; ++i) {
3916            final TaskRecord next = mTmpRecents.get(i);
3917            final TaskRecord prev = mTmpRecents.get(i + 1);
3918            if (next.mPrevAffiliate != prev) {
3919                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3920                        " setting prev=" + prev);
3921                next.setPrevAffiliate(prev);
3922                mTaskPersister.wakeup(next, false);
3923            }
3924            if (prev.mNextAffiliate != next) {
3925                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3926                        " setting next=" + next);
3927                prev.setNextAffiliate(next);
3928                mTaskPersister.wakeup(prev, false);
3929            }
3930            prev.inRecents = true;
3931        }
3932        // The last one is the beginning of the list and has no prev.
3933        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3934        if (last.mPrevAffiliate != null) {
3935            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3936            last.setPrevAffiliate(null);
3937            mTaskPersister.wakeup(last, false);
3938        }
3939
3940        // Insert the group back into mRecentTasks at start.
3941        mRecentTasks.addAll(start, mTmpRecents);
3942
3943        // Let the caller know where we left off.
3944        return start + tmpSize;
3945    }
3946
3947    /**
3948     * Update the recent tasks lists: make sure tasks should still be here (their
3949     * applications / activities still exist), update their availability, fixup ordering
3950     * of affiliations.
3951     */
3952    void cleanupRecentTasksLocked(int userId) {
3953        if (mRecentTasks == null) {
3954            // Happens when called from the packagemanager broadcast before boot.
3955            return;
3956        }
3957
3958        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3959        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3960        final IPackageManager pm = AppGlobals.getPackageManager();
3961        final ActivityInfo dummyAct = new ActivityInfo();
3962        final ApplicationInfo dummyApp = new ApplicationInfo();
3963
3964        int N = mRecentTasks.size();
3965
3966        int[] users = userId == UserHandle.USER_ALL
3967                ? getUsersLocked() : new int[] { userId };
3968        for (int user : users) {
3969            for (int i = 0; i < N; i++) {
3970                TaskRecord task = mRecentTasks.get(i);
3971                if (task.userId != user) {
3972                    // Only look at tasks for the user ID of interest.
3973                    continue;
3974                }
3975                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3976                    // This situation is broken, and we should just get rid of it now.
3977                    mRecentTasks.remove(i);
3978                    task.removedFromRecents(mTaskPersister);
3979                    i--;
3980                    N--;
3981                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3982                    continue;
3983                }
3984                // Check whether this activity is currently available.
3985                if (task.realActivity != null) {
3986                    ActivityInfo ai = availActCache.get(task.realActivity);
3987                    if (ai == null) {
3988                        try {
3989                            ai = pm.getActivityInfo(task.realActivity,
3990                                    PackageManager.GET_UNINSTALLED_PACKAGES
3991                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3992                        } catch (RemoteException e) {
3993                            // Will never happen.
3994                            continue;
3995                        }
3996                        if (ai == null) {
3997                            ai = dummyAct;
3998                        }
3999                        availActCache.put(task.realActivity, ai);
4000                    }
4001                    if (ai == dummyAct) {
4002                        // This could be either because the activity no longer exists, or the
4003                        // app is temporarily gone.  For the former we want to remove the recents
4004                        // entry; for the latter we want to mark it as unavailable.
4005                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4006                        if (app == null) {
4007                            try {
4008                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4009                                        PackageManager.GET_UNINSTALLED_PACKAGES
4010                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4011                            } catch (RemoteException e) {
4012                                // Will never happen.
4013                                continue;
4014                            }
4015                            if (app == null) {
4016                                app = dummyApp;
4017                            }
4018                            availAppCache.put(task.realActivity.getPackageName(), app);
4019                        }
4020                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4021                            // Doesn't exist any more!  Good-bye.
4022                            mRecentTasks.remove(i);
4023                            task.removedFromRecents(mTaskPersister);
4024                            i--;
4025                            N--;
4026                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4027                            continue;
4028                        } else {
4029                            // Otherwise just not available for now.
4030                            if (task.isAvailable) {
4031                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4032                                        + task);
4033                            }
4034                            task.isAvailable = false;
4035                        }
4036                    } else {
4037                        if (!ai.enabled || !ai.applicationInfo.enabled
4038                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4039                            if (task.isAvailable) {
4040                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4041                                        + task + " (enabled=" + ai.enabled + "/"
4042                                        + ai.applicationInfo.enabled +  " flags="
4043                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4044                            }
4045                            task.isAvailable = false;
4046                        } else {
4047                            if (!task.isAvailable) {
4048                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4049                                        + task);
4050                            }
4051                            task.isAvailable = true;
4052                        }
4053                    }
4054                }
4055            }
4056        }
4057
4058        // Verify the affiliate chain for each task.
4059        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4060        }
4061
4062        mTmpRecents.clear();
4063        // mRecentTasks is now in sorted, affiliated order.
4064    }
4065
4066    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4067        int N = mRecentTasks.size();
4068        TaskRecord top = task;
4069        int topIndex = taskIndex;
4070        while (top.mNextAffiliate != null && topIndex > 0) {
4071            top = top.mNextAffiliate;
4072            topIndex--;
4073        }
4074        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4075                + topIndex + " from intial " + taskIndex);
4076        // Find the end of the chain, doing a sanity check along the way.
4077        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4078        int endIndex = topIndex;
4079        TaskRecord prev = top;
4080        while (endIndex < N) {
4081            TaskRecord cur = mRecentTasks.get(endIndex);
4082            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4083                    + endIndex + " " + cur);
4084            if (cur == top) {
4085                // Verify start of the chain.
4086                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4087                    Slog.wtf(TAG, "Bad chain @" + endIndex
4088                            + ": first task has next affiliate: " + prev);
4089                    sane = false;
4090                    break;
4091                }
4092            } else {
4093                // Verify middle of the chain's next points back to the one before.
4094                if (cur.mNextAffiliate != prev
4095                        || cur.mNextAffiliateTaskId != prev.taskId) {
4096                    Slog.wtf(TAG, "Bad chain @" + endIndex
4097                            + ": middle task " + cur + " @" + endIndex
4098                            + " has bad next affiliate "
4099                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4100                            + ", expected " + prev);
4101                    sane = false;
4102                    break;
4103                }
4104            }
4105            if (cur.mPrevAffiliateTaskId == -1) {
4106                // Chain ends here.
4107                if (cur.mPrevAffiliate != null) {
4108                    Slog.wtf(TAG, "Bad chain @" + endIndex
4109                            + ": last task " + cur + " has previous affiliate "
4110                            + cur.mPrevAffiliate);
4111                    sane = false;
4112                }
4113                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4114                break;
4115            } else {
4116                // Verify middle of the chain's prev points to a valid item.
4117                if (cur.mPrevAffiliate == null) {
4118                    Slog.wtf(TAG, "Bad chain @" + endIndex
4119                            + ": task " + cur + " has previous affiliate "
4120                            + cur.mPrevAffiliate + " but should be id "
4121                            + cur.mPrevAffiliate);
4122                    sane = false;
4123                    break;
4124                }
4125            }
4126            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4127                Slog.wtf(TAG, "Bad chain @" + endIndex
4128                        + ": task " + cur + " has affiliated id "
4129                        + cur.mAffiliatedTaskId + " but should be "
4130                        + task.mAffiliatedTaskId);
4131                sane = false;
4132                break;
4133            }
4134            prev = cur;
4135            endIndex++;
4136            if (endIndex >= N) {
4137                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4138                        + ": last task " + prev);
4139                sane = false;
4140                break;
4141            }
4142        }
4143        if (sane) {
4144            if (endIndex < taskIndex) {
4145                Slog.wtf(TAG, "Bad chain @" + endIndex
4146                        + ": did not extend to task " + task + " @" + taskIndex);
4147                sane = false;
4148            }
4149        }
4150        if (sane) {
4151            // All looks good, we can just move all of the affiliated tasks
4152            // to the top.
4153            for (int i=topIndex; i<=endIndex; i++) {
4154                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4155                        + " from " + i + " to " + (i-topIndex));
4156                TaskRecord cur = mRecentTasks.remove(i);
4157                mRecentTasks.add(i-topIndex, cur);
4158            }
4159            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4160                    + " to " + endIndex);
4161            return true;
4162        }
4163
4164        // Whoops, couldn't do it.
4165        return false;
4166    }
4167
4168    final void addRecentTaskLocked(TaskRecord task) {
4169        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4170                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4171
4172        int N = mRecentTasks.size();
4173        // Quick case: check if the top-most recent task is the same.
4174        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4175            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4176            return;
4177        }
4178        // Another quick case: check if this is part of a set of affiliated
4179        // tasks that are at the top.
4180        if (isAffiliated && N > 0 && task.inRecents
4181                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4182            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4183                    + " at top when adding " + task);
4184            return;
4185        }
4186        // Another quick case: never add voice sessions.
4187        if (task.voiceSession != null) {
4188            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4189            return;
4190        }
4191
4192        boolean needAffiliationFix = false;
4193
4194        // Slightly less quick case: the task is already in recents, so all we need
4195        // to do is move it.
4196        if (task.inRecents) {
4197            int taskIndex = mRecentTasks.indexOf(task);
4198            if (taskIndex >= 0) {
4199                if (!isAffiliated) {
4200                    // Simple case: this is not an affiliated task, so we just move it to the front.
4201                    mRecentTasks.remove(taskIndex);
4202                    mRecentTasks.add(0, task);
4203                    notifyTaskPersisterLocked(task, false);
4204                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4205                            + " from " + taskIndex);
4206                    return;
4207                } else {
4208                    // More complicated: need to keep all affiliated tasks together.
4209                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4210                        // All went well.
4211                        return;
4212                    }
4213
4214                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4215                    // everything and then go through our general path of adding a new task.
4216                    needAffiliationFix = true;
4217                }
4218            } else {
4219                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4220                needAffiliationFix = true;
4221            }
4222        }
4223
4224        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4225        trimRecentsForTask(task, true);
4226
4227        N = mRecentTasks.size();
4228        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4229            final TaskRecord tr = mRecentTasks.remove(N - 1);
4230            tr.removedFromRecents(mTaskPersister);
4231            N--;
4232        }
4233        task.inRecents = true;
4234        if (!isAffiliated || needAffiliationFix) {
4235            // If this is a simple non-affiliated task, or we had some failure trying to
4236            // handle it as part of an affilated task, then just place it at the top.
4237            mRecentTasks.add(0, task);
4238        } else if (isAffiliated) {
4239            // If this is a new affiliated task, then move all of the affiliated tasks
4240            // to the front and insert this new one.
4241            TaskRecord other = task.mNextAffiliate;
4242            if (other == null) {
4243                other = task.mPrevAffiliate;
4244            }
4245            if (other != null) {
4246                int otherIndex = mRecentTasks.indexOf(other);
4247                if (otherIndex >= 0) {
4248                    // Insert new task at appropriate location.
4249                    int taskIndex;
4250                    if (other == task.mNextAffiliate) {
4251                        // We found the index of our next affiliation, which is who is
4252                        // before us in the list, so add after that point.
4253                        taskIndex = otherIndex+1;
4254                    } else {
4255                        // We found the index of our previous affiliation, which is who is
4256                        // after us in the list, so add at their position.
4257                        taskIndex = otherIndex;
4258                    }
4259                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4260                            + taskIndex + ": " + task);
4261                    mRecentTasks.add(taskIndex, task);
4262
4263                    // Now move everything to the front.
4264                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4265                        // All went well.
4266                        return;
4267                    }
4268
4269                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4270                    // everything and then go through our general path of adding a new task.
4271                    needAffiliationFix = true;
4272                } else {
4273                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4274                            + other);
4275                    needAffiliationFix = true;
4276                }
4277            } else {
4278                if (DEBUG_RECENTS) Slog.d(TAG,
4279                        "addRecent: adding affiliated task without next/prev:" + task);
4280                needAffiliationFix = true;
4281            }
4282        }
4283        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4284
4285        if (needAffiliationFix) {
4286            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4287            cleanupRecentTasksLocked(task.userId);
4288        }
4289    }
4290
4291    /**
4292     * If needed, remove oldest existing entries in recents that are for the same kind
4293     * of task as the given one.
4294     */
4295    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4296        int N = mRecentTasks.size();
4297        final Intent intent = task.intent;
4298        final boolean document = intent != null && intent.isDocument();
4299
4300        int maxRecents = task.maxRecents - 1;
4301        for (int i=0; i<N; i++) {
4302            final TaskRecord tr = mRecentTasks.get(i);
4303            if (task != tr) {
4304                if (task.userId != tr.userId) {
4305                    continue;
4306                }
4307                if (i > MAX_RECENT_BITMAPS) {
4308                    tr.freeLastThumbnail();
4309                }
4310                final Intent trIntent = tr.intent;
4311                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4312                    (intent == null || !intent.filterEquals(trIntent))) {
4313                    continue;
4314                }
4315                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4316                if (document && trIsDocument) {
4317                    // These are the same document activity (not necessarily the same doc).
4318                    if (maxRecents > 0) {
4319                        --maxRecents;
4320                        continue;
4321                    }
4322                    // Hit the maximum number of documents for this task. Fall through
4323                    // and remove this document from recents.
4324                } else if (document || trIsDocument) {
4325                    // Only one of these is a document. Not the droid we're looking for.
4326                    continue;
4327                }
4328            }
4329
4330            if (!doTrim) {
4331                // If the caller is not actually asking for a trim, just tell them we reached
4332                // a point where the trim would happen.
4333                return i;
4334            }
4335
4336            // Either task and tr are the same or, their affinities match or their intents match
4337            // and neither of them is a document, or they are documents using the same activity
4338            // and their maxRecents has been reached.
4339            tr.disposeThumbnail();
4340            mRecentTasks.remove(i);
4341            if (task != tr) {
4342                tr.removedFromRecents(mTaskPersister);
4343            }
4344            i--;
4345            N--;
4346            if (task.intent == null) {
4347                // If the new recent task we are adding is not fully
4348                // specified, then replace it with the existing recent task.
4349                task = tr;
4350            }
4351            notifyTaskPersisterLocked(tr, false);
4352        }
4353
4354        return -1;
4355    }
4356
4357    @Override
4358    public void reportActivityFullyDrawn(IBinder token) {
4359        synchronized (this) {
4360            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4361            if (r == null) {
4362                return;
4363            }
4364            r.reportFullyDrawnLocked();
4365        }
4366    }
4367
4368    @Override
4369    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4370        synchronized (this) {
4371            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4372            if (r == null) {
4373                return;
4374            }
4375            final long origId = Binder.clearCallingIdentity();
4376            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4377            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4378                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4379            if (config != null) {
4380                r.frozenBeforeDestroy = true;
4381                if (!updateConfigurationLocked(config, r, false, false)) {
4382                    mStackSupervisor.resumeTopActivitiesLocked();
4383                }
4384            }
4385            Binder.restoreCallingIdentity(origId);
4386        }
4387    }
4388
4389    @Override
4390    public int getRequestedOrientation(IBinder token) {
4391        synchronized (this) {
4392            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4393            if (r == null) {
4394                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4395            }
4396            return mWindowManager.getAppOrientation(r.appToken);
4397        }
4398    }
4399
4400    /**
4401     * This is the internal entry point for handling Activity.finish().
4402     *
4403     * @param token The Binder token referencing the Activity we want to finish.
4404     * @param resultCode Result code, if any, from this Activity.
4405     * @param resultData Result data (Intent), if any, from this Activity.
4406     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4407     *            the root Activity in the task.
4408     *
4409     * @return Returns true if the activity successfully finished, or false if it is still running.
4410     */
4411    @Override
4412    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4413            boolean finishTask) {
4414        // Refuse possible leaked file descriptors
4415        if (resultData != null && resultData.hasFileDescriptors() == true) {
4416            throw new IllegalArgumentException("File descriptors passed in Intent");
4417        }
4418
4419        synchronized(this) {
4420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4421            if (r == null) {
4422                return true;
4423            }
4424            // Keep track of the root activity of the task before we finish it
4425            TaskRecord tr = r.task;
4426            ActivityRecord rootR = tr.getRootActivity();
4427            // Do not allow task to finish in Lock Task mode.
4428            if (tr == mStackSupervisor.mLockTaskModeTask) {
4429                if (rootR == r) {
4430                    mStackSupervisor.showLockTaskToast();
4431                    return false;
4432                }
4433            }
4434            if (mController != null) {
4435                // Find the first activity that is not finishing.
4436                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4437                if (next != null) {
4438                    // ask watcher if this is allowed
4439                    boolean resumeOK = true;
4440                    try {
4441                        resumeOK = mController.activityResuming(next.packageName);
4442                    } catch (RemoteException e) {
4443                        mController = null;
4444                        Watchdog.getInstance().setActivityController(null);
4445                    }
4446
4447                    if (!resumeOK) {
4448                        return false;
4449                    }
4450                }
4451            }
4452            final long origId = Binder.clearCallingIdentity();
4453            try {
4454                boolean res;
4455                if (finishTask && r == rootR) {
4456                    // If requested, remove the task that is associated to this activity only if it
4457                    // was the root activity in the task.  The result code and data is ignored because
4458                    // we don't support returning them across task boundaries.
4459                    res = removeTaskByIdLocked(tr.taskId, 0);
4460                } else {
4461                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4462                            resultData, "app-request", true);
4463                }
4464                return res;
4465            } finally {
4466                Binder.restoreCallingIdentity(origId);
4467            }
4468        }
4469    }
4470
4471    @Override
4472    public final void finishHeavyWeightApp() {
4473        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4474                != PackageManager.PERMISSION_GRANTED) {
4475            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4476                    + Binder.getCallingPid()
4477                    + ", uid=" + Binder.getCallingUid()
4478                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4479            Slog.w(TAG, msg);
4480            throw new SecurityException(msg);
4481        }
4482
4483        synchronized(this) {
4484            if (mHeavyWeightProcess == null) {
4485                return;
4486            }
4487
4488            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4489                    mHeavyWeightProcess.activities);
4490            for (int i=0; i<activities.size(); i++) {
4491                ActivityRecord r = activities.get(i);
4492                if (!r.finishing) {
4493                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4494                            null, "finish-heavy", true);
4495                }
4496            }
4497
4498            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4499                    mHeavyWeightProcess.userId, 0));
4500            mHeavyWeightProcess = null;
4501        }
4502    }
4503
4504    @Override
4505    public void crashApplication(int uid, int initialPid, String packageName,
4506            String message) {
4507        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4508                != PackageManager.PERMISSION_GRANTED) {
4509            String msg = "Permission Denial: crashApplication() from pid="
4510                    + Binder.getCallingPid()
4511                    + ", uid=" + Binder.getCallingUid()
4512                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4513            Slog.w(TAG, msg);
4514            throw new SecurityException(msg);
4515        }
4516
4517        synchronized(this) {
4518            ProcessRecord proc = null;
4519
4520            // Figure out which process to kill.  We don't trust that initialPid
4521            // still has any relation to current pids, so must scan through the
4522            // list.
4523            synchronized (mPidsSelfLocked) {
4524                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4525                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4526                    if (p.uid != uid) {
4527                        continue;
4528                    }
4529                    if (p.pid == initialPid) {
4530                        proc = p;
4531                        break;
4532                    }
4533                    if (p.pkgList.containsKey(packageName)) {
4534                        proc = p;
4535                    }
4536                }
4537            }
4538
4539            if (proc == null) {
4540                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4541                        + " initialPid=" + initialPid
4542                        + " packageName=" + packageName);
4543                return;
4544            }
4545
4546            if (proc.thread != null) {
4547                if (proc.pid == Process.myPid()) {
4548                    Log.w(TAG, "crashApplication: trying to crash self!");
4549                    return;
4550                }
4551                long ident = Binder.clearCallingIdentity();
4552                try {
4553                    proc.thread.scheduleCrash(message);
4554                } catch (RemoteException e) {
4555                }
4556                Binder.restoreCallingIdentity(ident);
4557            }
4558        }
4559    }
4560
4561    @Override
4562    public final void finishSubActivity(IBinder token, String resultWho,
4563            int requestCode) {
4564        synchronized(this) {
4565            final long origId = Binder.clearCallingIdentity();
4566            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4567            if (r != null) {
4568                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4569            }
4570            Binder.restoreCallingIdentity(origId);
4571        }
4572    }
4573
4574    @Override
4575    public boolean finishActivityAffinity(IBinder token) {
4576        synchronized(this) {
4577            final long origId = Binder.clearCallingIdentity();
4578            try {
4579                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4580
4581                ActivityRecord rootR = r.task.getRootActivity();
4582                // Do not allow task to finish in Lock Task mode.
4583                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4584                    if (rootR == r) {
4585                        mStackSupervisor.showLockTaskToast();
4586                        return false;
4587                    }
4588                }
4589                boolean res = false;
4590                if (r != null) {
4591                    res = r.task.stack.finishActivityAffinityLocked(r);
4592                }
4593                return res;
4594            } finally {
4595                Binder.restoreCallingIdentity(origId);
4596            }
4597        }
4598    }
4599
4600    @Override
4601    public void finishVoiceTask(IVoiceInteractionSession session) {
4602        synchronized(this) {
4603            final long origId = Binder.clearCallingIdentity();
4604            try {
4605                mStackSupervisor.finishVoiceTask(session);
4606            } finally {
4607                Binder.restoreCallingIdentity(origId);
4608            }
4609        }
4610
4611    }
4612
4613    @Override
4614    public boolean releaseActivityInstance(IBinder token) {
4615        synchronized(this) {
4616            final long origId = Binder.clearCallingIdentity();
4617            try {
4618                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4619                if (r.task == null || r.task.stack == null) {
4620                    return false;
4621                }
4622                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4623            } finally {
4624                Binder.restoreCallingIdentity(origId);
4625            }
4626        }
4627    }
4628
4629    @Override
4630    public void releaseSomeActivities(IApplicationThread appInt) {
4631        synchronized(this) {
4632            final long origId = Binder.clearCallingIdentity();
4633            try {
4634                ProcessRecord app = getRecordForAppLocked(appInt);
4635                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4636            } finally {
4637                Binder.restoreCallingIdentity(origId);
4638            }
4639        }
4640    }
4641
4642    @Override
4643    public boolean willActivityBeVisible(IBinder token) {
4644        synchronized(this) {
4645            ActivityStack stack = ActivityRecord.getStackLocked(token);
4646            if (stack != null) {
4647                return stack.willActivityBeVisibleLocked(token);
4648            }
4649            return false;
4650        }
4651    }
4652
4653    @Override
4654    public void overridePendingTransition(IBinder token, String packageName,
4655            int enterAnim, int exitAnim) {
4656        synchronized(this) {
4657            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4658            if (self == null) {
4659                return;
4660            }
4661
4662            final long origId = Binder.clearCallingIdentity();
4663
4664            if (self.state == ActivityState.RESUMED
4665                    || self.state == ActivityState.PAUSING) {
4666                mWindowManager.overridePendingAppTransition(packageName,
4667                        enterAnim, exitAnim, null);
4668            }
4669
4670            Binder.restoreCallingIdentity(origId);
4671        }
4672    }
4673
4674    /**
4675     * Main function for removing an existing process from the activity manager
4676     * as a result of that process going away.  Clears out all connections
4677     * to the process.
4678     */
4679    private final void handleAppDiedLocked(ProcessRecord app,
4680            boolean restarting, boolean allowRestart) {
4681        int pid = app.pid;
4682        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4683        if (!restarting) {
4684            removeLruProcessLocked(app);
4685            if (pid > 0) {
4686                ProcessList.remove(pid);
4687            }
4688        }
4689
4690        if (mProfileProc == app) {
4691            clearProfilerLocked();
4692        }
4693
4694        // Remove this application's activities from active lists.
4695        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4696
4697        app.activities.clear();
4698
4699        if (app.instrumentationClass != null) {
4700            Slog.w(TAG, "Crash of app " + app.processName
4701                  + " running instrumentation " + app.instrumentationClass);
4702            Bundle info = new Bundle();
4703            info.putString("shortMsg", "Process crashed.");
4704            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4705        }
4706
4707        if (!restarting) {
4708            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4709                // If there was nothing to resume, and we are not already
4710                // restarting this process, but there is a visible activity that
4711                // is hosted by the process...  then make sure all visible
4712                // activities are running, taking care of restarting this
4713                // process.
4714                if (hasVisibleActivities) {
4715                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4716                }
4717            }
4718        }
4719    }
4720
4721    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4722        IBinder threadBinder = thread.asBinder();
4723        // Find the application record.
4724        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4725            ProcessRecord rec = mLruProcesses.get(i);
4726            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4727                return i;
4728            }
4729        }
4730        return -1;
4731    }
4732
4733    final ProcessRecord getRecordForAppLocked(
4734            IApplicationThread thread) {
4735        if (thread == null) {
4736            return null;
4737        }
4738
4739        int appIndex = getLRURecordIndexForAppLocked(thread);
4740        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4741    }
4742
4743    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4744        // If there are no longer any background processes running,
4745        // and the app that died was not running instrumentation,
4746        // then tell everyone we are now low on memory.
4747        boolean haveBg = false;
4748        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4749            ProcessRecord rec = mLruProcesses.get(i);
4750            if (rec.thread != null
4751                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4752                haveBg = true;
4753                break;
4754            }
4755        }
4756
4757        if (!haveBg) {
4758            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4759            if (doReport) {
4760                long now = SystemClock.uptimeMillis();
4761                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4762                    doReport = false;
4763                } else {
4764                    mLastMemUsageReportTime = now;
4765                }
4766            }
4767            final ArrayList<ProcessMemInfo> memInfos
4768                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4769            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4770            long now = SystemClock.uptimeMillis();
4771            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4772                ProcessRecord rec = mLruProcesses.get(i);
4773                if (rec == dyingProc || rec.thread == null) {
4774                    continue;
4775                }
4776                if (doReport) {
4777                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4778                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4779                }
4780                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4781                    // The low memory report is overriding any current
4782                    // state for a GC request.  Make sure to do
4783                    // heavy/important/visible/foreground processes first.
4784                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4785                        rec.lastRequestedGc = 0;
4786                    } else {
4787                        rec.lastRequestedGc = rec.lastLowMemory;
4788                    }
4789                    rec.reportLowMemory = true;
4790                    rec.lastLowMemory = now;
4791                    mProcessesToGc.remove(rec);
4792                    addProcessToGcListLocked(rec);
4793                }
4794            }
4795            if (doReport) {
4796                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4797                mHandler.sendMessage(msg);
4798            }
4799            scheduleAppGcsLocked();
4800        }
4801    }
4802
4803    final void appDiedLocked(ProcessRecord app) {
4804       appDiedLocked(app, app.pid, app.thread);
4805    }
4806
4807    final void appDiedLocked(ProcessRecord app, int pid,
4808            IApplicationThread thread) {
4809
4810        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4811        synchronized (stats) {
4812            stats.noteProcessDiedLocked(app.info.uid, pid);
4813        }
4814
4815        Process.killProcessGroup(app.info.uid, pid);
4816
4817        // Clean up already done if the process has been re-started.
4818        if (app.pid == pid && app.thread != null &&
4819                app.thread.asBinder() == thread.asBinder()) {
4820            boolean doLowMem = app.instrumentationClass == null;
4821            boolean doOomAdj = doLowMem;
4822            if (!app.killedByAm) {
4823                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4824                        + ") has died.");
4825                mAllowLowerMemLevel = true;
4826            } else {
4827                // Note that we always want to do oom adj to update our state with the
4828                // new number of procs.
4829                mAllowLowerMemLevel = false;
4830                doLowMem = false;
4831            }
4832            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4833            if (DEBUG_CLEANUP) Slog.v(
4834                TAG, "Dying app: " + app + ", pid: " + pid
4835                + ", thread: " + thread.asBinder());
4836            handleAppDiedLocked(app, false, true);
4837
4838            if (doOomAdj) {
4839                updateOomAdjLocked();
4840            }
4841            if (doLowMem) {
4842                doLowMemReportIfNeededLocked(app);
4843            }
4844        } else if (app.pid != pid) {
4845            // A new process has already been started.
4846            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4847                    + ") has died and restarted (pid " + app.pid + ").");
4848            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4849        } else if (DEBUG_PROCESSES) {
4850            Slog.d(TAG, "Received spurious death notification for thread "
4851                    + thread.asBinder());
4852        }
4853    }
4854
4855    /**
4856     * If a stack trace dump file is configured, dump process stack traces.
4857     * @param clearTraces causes the dump file to be erased prior to the new
4858     *    traces being written, if true; when false, the new traces will be
4859     *    appended to any existing file content.
4860     * @param firstPids of dalvik VM processes to dump stack traces for first
4861     * @param lastPids of dalvik VM processes to dump stack traces for last
4862     * @param nativeProcs optional list of native process names to dump stack crawls
4863     * @return file containing stack traces, or null if no dump file is configured
4864     */
4865    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4866            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4867        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4868        if (tracesPath == null || tracesPath.length() == 0) {
4869            return null;
4870        }
4871
4872        File tracesFile = new File(tracesPath);
4873        try {
4874            File tracesDir = tracesFile.getParentFile();
4875            if (!tracesDir.exists()) {
4876                tracesDir.mkdirs();
4877                if (!SELinux.restorecon(tracesDir)) {
4878                    return null;
4879                }
4880            }
4881            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4882
4883            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4884            tracesFile.createNewFile();
4885            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4886        } catch (IOException e) {
4887            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4888            return null;
4889        }
4890
4891        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4892        return tracesFile;
4893    }
4894
4895    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4896            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4897        // Use a FileObserver to detect when traces finish writing.
4898        // The order of traces is considered important to maintain for legibility.
4899        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4900            @Override
4901            public synchronized void onEvent(int event, String path) { notify(); }
4902        };
4903
4904        try {
4905            observer.startWatching();
4906
4907            // First collect all of the stacks of the most important pids.
4908            if (firstPids != null) {
4909                try {
4910                    int num = firstPids.size();
4911                    for (int i = 0; i < num; i++) {
4912                        synchronized (observer) {
4913                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4914                            observer.wait(200);  // Wait for write-close, give up after 200msec
4915                        }
4916                    }
4917                } catch (InterruptedException e) {
4918                    Log.wtf(TAG, e);
4919                }
4920            }
4921
4922            // Next collect the stacks of the native pids
4923            if (nativeProcs != null) {
4924                int[] pids = Process.getPidsForCommands(nativeProcs);
4925                if (pids != null) {
4926                    for (int pid : pids) {
4927                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4928                    }
4929                }
4930            }
4931
4932            // Lastly, measure CPU usage.
4933            if (processCpuTracker != null) {
4934                processCpuTracker.init();
4935                System.gc();
4936                processCpuTracker.update();
4937                try {
4938                    synchronized (processCpuTracker) {
4939                        processCpuTracker.wait(500); // measure over 1/2 second.
4940                    }
4941                } catch (InterruptedException e) {
4942                }
4943                processCpuTracker.update();
4944
4945                // We'll take the stack crawls of just the top apps using CPU.
4946                final int N = processCpuTracker.countWorkingStats();
4947                int numProcs = 0;
4948                for (int i=0; i<N && numProcs<5; i++) {
4949                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4950                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4951                        numProcs++;
4952                        try {
4953                            synchronized (observer) {
4954                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4955                                observer.wait(200);  // Wait for write-close, give up after 200msec
4956                            }
4957                        } catch (InterruptedException e) {
4958                            Log.wtf(TAG, e);
4959                        }
4960
4961                    }
4962                }
4963            }
4964        } finally {
4965            observer.stopWatching();
4966        }
4967    }
4968
4969    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4970        if (true || IS_USER_BUILD) {
4971            return;
4972        }
4973        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4974        if (tracesPath == null || tracesPath.length() == 0) {
4975            return;
4976        }
4977
4978        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4979        StrictMode.allowThreadDiskWrites();
4980        try {
4981            final File tracesFile = new File(tracesPath);
4982            final File tracesDir = tracesFile.getParentFile();
4983            final File tracesTmp = new File(tracesDir, "__tmp__");
4984            try {
4985                if (!tracesDir.exists()) {
4986                    tracesDir.mkdirs();
4987                    if (!SELinux.restorecon(tracesDir.getPath())) {
4988                        return;
4989                    }
4990                }
4991                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4992
4993                if (tracesFile.exists()) {
4994                    tracesTmp.delete();
4995                    tracesFile.renameTo(tracesTmp);
4996                }
4997                StringBuilder sb = new StringBuilder();
4998                Time tobj = new Time();
4999                tobj.set(System.currentTimeMillis());
5000                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5001                sb.append(": ");
5002                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5003                sb.append(" since ");
5004                sb.append(msg);
5005                FileOutputStream fos = new FileOutputStream(tracesFile);
5006                fos.write(sb.toString().getBytes());
5007                if (app == null) {
5008                    fos.write("\n*** No application process!".getBytes());
5009                }
5010                fos.close();
5011                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5012            } catch (IOException e) {
5013                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5014                return;
5015            }
5016
5017            if (app != null) {
5018                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5019                firstPids.add(app.pid);
5020                dumpStackTraces(tracesPath, firstPids, null, null, null);
5021            }
5022
5023            File lastTracesFile = null;
5024            File curTracesFile = null;
5025            for (int i=9; i>=0; i--) {
5026                String name = String.format(Locale.US, "slow%02d.txt", i);
5027                curTracesFile = new File(tracesDir, name);
5028                if (curTracesFile.exists()) {
5029                    if (lastTracesFile != null) {
5030                        curTracesFile.renameTo(lastTracesFile);
5031                    } else {
5032                        curTracesFile.delete();
5033                    }
5034                }
5035                lastTracesFile = curTracesFile;
5036            }
5037            tracesFile.renameTo(curTracesFile);
5038            if (tracesTmp.exists()) {
5039                tracesTmp.renameTo(tracesFile);
5040            }
5041        } finally {
5042            StrictMode.setThreadPolicy(oldPolicy);
5043        }
5044    }
5045
5046    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5047            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5048        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5049        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5050
5051        if (mController != null) {
5052            try {
5053                // 0 == continue, -1 = kill process immediately
5054                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5055                if (res < 0 && app.pid != MY_PID) {
5056                    app.kill("anr", true);
5057                }
5058            } catch (RemoteException e) {
5059                mController = null;
5060                Watchdog.getInstance().setActivityController(null);
5061            }
5062        }
5063
5064        long anrTime = SystemClock.uptimeMillis();
5065        if (MONITOR_CPU_USAGE) {
5066            updateCpuStatsNow();
5067        }
5068
5069        synchronized (this) {
5070            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5071            if (mShuttingDown) {
5072                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5073                return;
5074            } else if (app.notResponding) {
5075                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5076                return;
5077            } else if (app.crashing) {
5078                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5079                return;
5080            }
5081
5082            // In case we come through here for the same app before completing
5083            // this one, mark as anring now so we will bail out.
5084            app.notResponding = true;
5085
5086            // Log the ANR to the event log.
5087            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5088                    app.processName, app.info.flags, annotation);
5089
5090            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5091            firstPids.add(app.pid);
5092
5093            int parentPid = app.pid;
5094            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5095            if (parentPid != app.pid) firstPids.add(parentPid);
5096
5097            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5098
5099            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5100                ProcessRecord r = mLruProcesses.get(i);
5101                if (r != null && r.thread != null) {
5102                    int pid = r.pid;
5103                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5104                        if (r.persistent) {
5105                            firstPids.add(pid);
5106                        } else {
5107                            lastPids.put(pid, Boolean.TRUE);
5108                        }
5109                    }
5110                }
5111            }
5112        }
5113
5114        // Log the ANR to the main log.
5115        StringBuilder info = new StringBuilder();
5116        info.setLength(0);
5117        info.append("ANR in ").append(app.processName);
5118        if (activity != null && activity.shortComponentName != null) {
5119            info.append(" (").append(activity.shortComponentName).append(")");
5120        }
5121        info.append("\n");
5122        info.append("PID: ").append(app.pid).append("\n");
5123        if (annotation != null) {
5124            info.append("Reason: ").append(annotation).append("\n");
5125        }
5126        if (parent != null && parent != activity) {
5127            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5128        }
5129
5130        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5131
5132        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5133                NATIVE_STACKS_OF_INTEREST);
5134
5135        String cpuInfo = null;
5136        if (MONITOR_CPU_USAGE) {
5137            updateCpuStatsNow();
5138            synchronized (mProcessCpuTracker) {
5139                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5140            }
5141            info.append(processCpuTracker.printCurrentLoad());
5142            info.append(cpuInfo);
5143        }
5144
5145        info.append(processCpuTracker.printCurrentState(anrTime));
5146
5147        Slog.e(TAG, info.toString());
5148        if (tracesFile == null) {
5149            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5150            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5151        }
5152
5153        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5154                cpuInfo, tracesFile, null);
5155
5156        if (mController != null) {
5157            try {
5158                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5159                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5160                if (res != 0) {
5161                    if (res < 0 && app.pid != MY_PID) {
5162                        app.kill("anr", true);
5163                    } else {
5164                        synchronized (this) {
5165                            mServices.scheduleServiceTimeoutLocked(app);
5166                        }
5167                    }
5168                    return;
5169                }
5170            } catch (RemoteException e) {
5171                mController = null;
5172                Watchdog.getInstance().setActivityController(null);
5173            }
5174        }
5175
5176        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5177        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5178                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5179
5180        synchronized (this) {
5181            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5182                app.kill("bg anr", true);
5183                return;
5184            }
5185
5186            // Set the app's notResponding state, and look up the errorReportReceiver
5187            makeAppNotRespondingLocked(app,
5188                    activity != null ? activity.shortComponentName : null,
5189                    annotation != null ? "ANR " + annotation : "ANR",
5190                    info.toString());
5191
5192            // Bring up the infamous App Not Responding dialog
5193            Message msg = Message.obtain();
5194            HashMap<String, Object> map = new HashMap<String, Object>();
5195            msg.what = SHOW_NOT_RESPONDING_MSG;
5196            msg.obj = map;
5197            msg.arg1 = aboveSystem ? 1 : 0;
5198            map.put("app", app);
5199            if (activity != null) {
5200                map.put("activity", activity);
5201            }
5202
5203            mHandler.sendMessage(msg);
5204        }
5205    }
5206
5207    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5208        if (!mLaunchWarningShown) {
5209            mLaunchWarningShown = true;
5210            mHandler.post(new Runnable() {
5211                @Override
5212                public void run() {
5213                    synchronized (ActivityManagerService.this) {
5214                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5215                        d.show();
5216                        mHandler.postDelayed(new Runnable() {
5217                            @Override
5218                            public void run() {
5219                                synchronized (ActivityManagerService.this) {
5220                                    d.dismiss();
5221                                    mLaunchWarningShown = false;
5222                                }
5223                            }
5224                        }, 4000);
5225                    }
5226                }
5227            });
5228        }
5229    }
5230
5231    @Override
5232    public boolean clearApplicationUserData(final String packageName,
5233            final IPackageDataObserver observer, int userId) {
5234        enforceNotIsolatedCaller("clearApplicationUserData");
5235        int uid = Binder.getCallingUid();
5236        int pid = Binder.getCallingPid();
5237        userId = handleIncomingUser(pid, uid,
5238                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5239        long callingId = Binder.clearCallingIdentity();
5240        try {
5241            IPackageManager pm = AppGlobals.getPackageManager();
5242            int pkgUid = -1;
5243            synchronized(this) {
5244                try {
5245                    pkgUid = pm.getPackageUid(packageName, userId);
5246                } catch (RemoteException e) {
5247                }
5248                if (pkgUid == -1) {
5249                    Slog.w(TAG, "Invalid packageName: " + packageName);
5250                    if (observer != null) {
5251                        try {
5252                            observer.onRemoveCompleted(packageName, false);
5253                        } catch (RemoteException e) {
5254                            Slog.i(TAG, "Observer no longer exists.");
5255                        }
5256                    }
5257                    return false;
5258                }
5259                if (uid == pkgUid || checkComponentPermission(
5260                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5261                        pid, uid, -1, true)
5262                        == PackageManager.PERMISSION_GRANTED) {
5263                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5264                } else {
5265                    throw new SecurityException("PID " + pid + " does not have permission "
5266                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5267                                    + " of package " + packageName);
5268                }
5269
5270                // Remove all tasks match the cleared application package and user
5271                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5272                    final TaskRecord tr = mRecentTasks.get(i);
5273                    final String taskPackageName =
5274                            tr.getBaseIntent().getComponent().getPackageName();
5275                    if (tr.userId != userId) continue;
5276                    if (!taskPackageName.equals(packageName)) continue;
5277                    removeTaskByIdLocked(tr.taskId, 0);
5278                }
5279            }
5280
5281            try {
5282                // Clear application user data
5283                pm.clearApplicationUserData(packageName, observer, userId);
5284
5285                synchronized(this) {
5286                    // Remove all permissions granted from/to this package
5287                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5288                }
5289
5290                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5291                        Uri.fromParts("package", packageName, null));
5292                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5293                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5294                        null, null, 0, null, null, null, false, false, userId);
5295            } catch (RemoteException e) {
5296            }
5297        } finally {
5298            Binder.restoreCallingIdentity(callingId);
5299        }
5300        return true;
5301    }
5302
5303    @Override
5304    public void killBackgroundProcesses(final String packageName, int userId) {
5305        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5306                != PackageManager.PERMISSION_GRANTED &&
5307                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5308                        != PackageManager.PERMISSION_GRANTED) {
5309            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5310                    + Binder.getCallingPid()
5311                    + ", uid=" + Binder.getCallingUid()
5312                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5313            Slog.w(TAG, msg);
5314            throw new SecurityException(msg);
5315        }
5316
5317        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5318                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5319        long callingId = Binder.clearCallingIdentity();
5320        try {
5321            IPackageManager pm = AppGlobals.getPackageManager();
5322            synchronized(this) {
5323                int appId = -1;
5324                try {
5325                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5326                } catch (RemoteException e) {
5327                }
5328                if (appId == -1) {
5329                    Slog.w(TAG, "Invalid packageName: " + packageName);
5330                    return;
5331                }
5332                killPackageProcessesLocked(packageName, appId, userId,
5333                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5334            }
5335        } finally {
5336            Binder.restoreCallingIdentity(callingId);
5337        }
5338    }
5339
5340    @Override
5341    public void killAllBackgroundProcesses() {
5342        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5343                != PackageManager.PERMISSION_GRANTED) {
5344            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5345                    + Binder.getCallingPid()
5346                    + ", uid=" + Binder.getCallingUid()
5347                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5348            Slog.w(TAG, msg);
5349            throw new SecurityException(msg);
5350        }
5351
5352        long callingId = Binder.clearCallingIdentity();
5353        try {
5354            synchronized(this) {
5355                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5356                final int NP = mProcessNames.getMap().size();
5357                for (int ip=0; ip<NP; ip++) {
5358                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5359                    final int NA = apps.size();
5360                    for (int ia=0; ia<NA; ia++) {
5361                        ProcessRecord app = apps.valueAt(ia);
5362                        if (app.persistent) {
5363                            // we don't kill persistent processes
5364                            continue;
5365                        }
5366                        if (app.removed) {
5367                            procs.add(app);
5368                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5369                            app.removed = true;
5370                            procs.add(app);
5371                        }
5372                    }
5373                }
5374
5375                int N = procs.size();
5376                for (int i=0; i<N; i++) {
5377                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5378                }
5379                mAllowLowerMemLevel = true;
5380                updateOomAdjLocked();
5381                doLowMemReportIfNeededLocked(null);
5382            }
5383        } finally {
5384            Binder.restoreCallingIdentity(callingId);
5385        }
5386    }
5387
5388    @Override
5389    public void forceStopPackage(final String packageName, int userId) {
5390        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5391                != PackageManager.PERMISSION_GRANTED) {
5392            String msg = "Permission Denial: forceStopPackage() from pid="
5393                    + Binder.getCallingPid()
5394                    + ", uid=" + Binder.getCallingUid()
5395                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5396            Slog.w(TAG, msg);
5397            throw new SecurityException(msg);
5398        }
5399        final int callingPid = Binder.getCallingPid();
5400        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5401                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5402        long callingId = Binder.clearCallingIdentity();
5403        try {
5404            IPackageManager pm = AppGlobals.getPackageManager();
5405            synchronized(this) {
5406                int[] users = userId == UserHandle.USER_ALL
5407                        ? getUsersLocked() : new int[] { userId };
5408                for (int user : users) {
5409                    int pkgUid = -1;
5410                    try {
5411                        pkgUid = pm.getPackageUid(packageName, user);
5412                    } catch (RemoteException e) {
5413                    }
5414                    if (pkgUid == -1) {
5415                        Slog.w(TAG, "Invalid packageName: " + packageName);
5416                        continue;
5417                    }
5418                    try {
5419                        pm.setPackageStoppedState(packageName, true, user);
5420                    } catch (RemoteException e) {
5421                    } catch (IllegalArgumentException e) {
5422                        Slog.w(TAG, "Failed trying to unstop package "
5423                                + packageName + ": " + e);
5424                    }
5425                    if (isUserRunningLocked(user, false)) {
5426                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5427                    }
5428                }
5429            }
5430        } finally {
5431            Binder.restoreCallingIdentity(callingId);
5432        }
5433    }
5434
5435    @Override
5436    public void addPackageDependency(String packageName) {
5437        synchronized (this) {
5438            int callingPid = Binder.getCallingPid();
5439            if (callingPid == Process.myPid()) {
5440                //  Yeah, um, no.
5441                Slog.w(TAG, "Can't addPackageDependency on system process");
5442                return;
5443            }
5444            ProcessRecord proc;
5445            synchronized (mPidsSelfLocked) {
5446                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5447            }
5448            if (proc != null) {
5449                if (proc.pkgDeps == null) {
5450                    proc.pkgDeps = new ArraySet<String>(1);
5451                }
5452                proc.pkgDeps.add(packageName);
5453            }
5454        }
5455    }
5456
5457    /*
5458     * The pkg name and app id have to be specified.
5459     */
5460    @Override
5461    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5462        if (pkg == null) {
5463            return;
5464        }
5465        // Make sure the uid is valid.
5466        if (appid < 0) {
5467            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5468            return;
5469        }
5470        int callerUid = Binder.getCallingUid();
5471        // Only the system server can kill an application
5472        if (callerUid == Process.SYSTEM_UID) {
5473            // Post an aysnc message to kill the application
5474            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5475            msg.arg1 = appid;
5476            msg.arg2 = 0;
5477            Bundle bundle = new Bundle();
5478            bundle.putString("pkg", pkg);
5479            bundle.putString("reason", reason);
5480            msg.obj = bundle;
5481            mHandler.sendMessage(msg);
5482        } else {
5483            throw new SecurityException(callerUid + " cannot kill pkg: " +
5484                    pkg);
5485        }
5486    }
5487
5488    @Override
5489    public void closeSystemDialogs(String reason) {
5490        enforceNotIsolatedCaller("closeSystemDialogs");
5491
5492        final int pid = Binder.getCallingPid();
5493        final int uid = Binder.getCallingUid();
5494        final long origId = Binder.clearCallingIdentity();
5495        try {
5496            synchronized (this) {
5497                // Only allow this from foreground processes, so that background
5498                // applications can't abuse it to prevent system UI from being shown.
5499                if (uid >= Process.FIRST_APPLICATION_UID) {
5500                    ProcessRecord proc;
5501                    synchronized (mPidsSelfLocked) {
5502                        proc = mPidsSelfLocked.get(pid);
5503                    }
5504                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5505                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5506                                + " from background process " + proc);
5507                        return;
5508                    }
5509                }
5510                closeSystemDialogsLocked(reason);
5511            }
5512        } finally {
5513            Binder.restoreCallingIdentity(origId);
5514        }
5515    }
5516
5517    void closeSystemDialogsLocked(String reason) {
5518        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5519        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5520                | Intent.FLAG_RECEIVER_FOREGROUND);
5521        if (reason != null) {
5522            intent.putExtra("reason", reason);
5523        }
5524        mWindowManager.closeSystemDialogs(reason);
5525
5526        mStackSupervisor.closeSystemDialogsLocked();
5527
5528        broadcastIntentLocked(null, null, intent, null,
5529                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5530                Process.SYSTEM_UID, UserHandle.USER_ALL);
5531    }
5532
5533    @Override
5534    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5535        enforceNotIsolatedCaller("getProcessMemoryInfo");
5536        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5537        for (int i=pids.length-1; i>=0; i--) {
5538            ProcessRecord proc;
5539            int oomAdj;
5540            synchronized (this) {
5541                synchronized (mPidsSelfLocked) {
5542                    proc = mPidsSelfLocked.get(pids[i]);
5543                    oomAdj = proc != null ? proc.setAdj : 0;
5544                }
5545            }
5546            infos[i] = new Debug.MemoryInfo();
5547            Debug.getMemoryInfo(pids[i], infos[i]);
5548            if (proc != null) {
5549                synchronized (this) {
5550                    if (proc.thread != null && proc.setAdj == oomAdj) {
5551                        // Record this for posterity if the process has been stable.
5552                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5553                                infos[i].getTotalUss(), false, proc.pkgList);
5554                    }
5555                }
5556            }
5557        }
5558        return infos;
5559    }
5560
5561    @Override
5562    public long[] getProcessPss(int[] pids) {
5563        enforceNotIsolatedCaller("getProcessPss");
5564        long[] pss = new long[pids.length];
5565        for (int i=pids.length-1; i>=0; i--) {
5566            ProcessRecord proc;
5567            int oomAdj;
5568            synchronized (this) {
5569                synchronized (mPidsSelfLocked) {
5570                    proc = mPidsSelfLocked.get(pids[i]);
5571                    oomAdj = proc != null ? proc.setAdj : 0;
5572                }
5573            }
5574            long[] tmpUss = new long[1];
5575            pss[i] = Debug.getPss(pids[i], tmpUss);
5576            if (proc != null) {
5577                synchronized (this) {
5578                    if (proc.thread != null && proc.setAdj == oomAdj) {
5579                        // Record this for posterity if the process has been stable.
5580                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5581                    }
5582                }
5583            }
5584        }
5585        return pss;
5586    }
5587
5588    @Override
5589    public void killApplicationProcess(String processName, int uid) {
5590        if (processName == null) {
5591            return;
5592        }
5593
5594        int callerUid = Binder.getCallingUid();
5595        // Only the system server can kill an application
5596        if (callerUid == Process.SYSTEM_UID) {
5597            synchronized (this) {
5598                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5599                if (app != null && app.thread != null) {
5600                    try {
5601                        app.thread.scheduleSuicide();
5602                    } catch (RemoteException e) {
5603                        // If the other end already died, then our work here is done.
5604                    }
5605                } else {
5606                    Slog.w(TAG, "Process/uid not found attempting kill of "
5607                            + processName + " / " + uid);
5608                }
5609            }
5610        } else {
5611            throw new SecurityException(callerUid + " cannot kill app process: " +
5612                    processName);
5613        }
5614    }
5615
5616    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5617        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5618                false, true, false, false, UserHandle.getUserId(uid), reason);
5619        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5620                Uri.fromParts("package", packageName, null));
5621        if (!mProcessesReady) {
5622            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5623                    | Intent.FLAG_RECEIVER_FOREGROUND);
5624        }
5625        intent.putExtra(Intent.EXTRA_UID, uid);
5626        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5627        broadcastIntentLocked(null, null, intent,
5628                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5629                false, false,
5630                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5631    }
5632
5633    private void forceStopUserLocked(int userId, String reason) {
5634        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5635        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5636        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5637                | Intent.FLAG_RECEIVER_FOREGROUND);
5638        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5639        broadcastIntentLocked(null, null, intent,
5640                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5641                false, false,
5642                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5643    }
5644
5645    private final boolean killPackageProcessesLocked(String packageName, int appId,
5646            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5647            boolean doit, boolean evenPersistent, String reason) {
5648        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5649
5650        // Remove all processes this package may have touched: all with the
5651        // same UID (except for the system or root user), and all whose name
5652        // matches the package name.
5653        final int NP = mProcessNames.getMap().size();
5654        for (int ip=0; ip<NP; ip++) {
5655            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5656            final int NA = apps.size();
5657            for (int ia=0; ia<NA; ia++) {
5658                ProcessRecord app = apps.valueAt(ia);
5659                if (app.persistent && !evenPersistent) {
5660                    // we don't kill persistent processes
5661                    continue;
5662                }
5663                if (app.removed) {
5664                    if (doit) {
5665                        procs.add(app);
5666                    }
5667                    continue;
5668                }
5669
5670                // Skip process if it doesn't meet our oom adj requirement.
5671                if (app.setAdj < minOomAdj) {
5672                    continue;
5673                }
5674
5675                // If no package is specified, we call all processes under the
5676                // give user id.
5677                if (packageName == null) {
5678                    if (app.userId != userId) {
5679                        continue;
5680                    }
5681                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5682                        continue;
5683                    }
5684                // Package has been specified, we want to hit all processes
5685                // that match it.  We need to qualify this by the processes
5686                // that are running under the specified app and user ID.
5687                } else {
5688                    final boolean isDep = app.pkgDeps != null
5689                            && app.pkgDeps.contains(packageName);
5690                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5691                        continue;
5692                    }
5693                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5694                        continue;
5695                    }
5696                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5697                        continue;
5698                    }
5699                }
5700
5701                // Process has passed all conditions, kill it!
5702                if (!doit) {
5703                    return true;
5704                }
5705                app.removed = true;
5706                procs.add(app);
5707            }
5708        }
5709
5710        int N = procs.size();
5711        for (int i=0; i<N; i++) {
5712            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5713        }
5714        updateOomAdjLocked();
5715        return N > 0;
5716    }
5717
5718    private final boolean forceStopPackageLocked(String name, int appId,
5719            boolean callerWillRestart, boolean purgeCache, boolean doit,
5720            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5721        int i;
5722        int N;
5723
5724        if (userId == UserHandle.USER_ALL && name == null) {
5725            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5726        }
5727
5728        if (appId < 0 && name != null) {
5729            try {
5730                appId = UserHandle.getAppId(
5731                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5732            } catch (RemoteException e) {
5733            }
5734        }
5735
5736        if (doit) {
5737            if (name != null) {
5738                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5739                        + " user=" + userId + ": " + reason);
5740            } else {
5741                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5742            }
5743
5744            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5745            for (int ip=pmap.size()-1; ip>=0; ip--) {
5746                SparseArray<Long> ba = pmap.valueAt(ip);
5747                for (i=ba.size()-1; i>=0; i--) {
5748                    boolean remove = false;
5749                    final int entUid = ba.keyAt(i);
5750                    if (name != null) {
5751                        if (userId == UserHandle.USER_ALL) {
5752                            if (UserHandle.getAppId(entUid) == appId) {
5753                                remove = true;
5754                            }
5755                        } else {
5756                            if (entUid == UserHandle.getUid(userId, appId)) {
5757                                remove = true;
5758                            }
5759                        }
5760                    } else if (UserHandle.getUserId(entUid) == userId) {
5761                        remove = true;
5762                    }
5763                    if (remove) {
5764                        ba.removeAt(i);
5765                    }
5766                }
5767                if (ba.size() == 0) {
5768                    pmap.removeAt(ip);
5769                }
5770            }
5771        }
5772
5773        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5774                -100, callerWillRestart, true, doit, evenPersistent,
5775                name == null ? ("stop user " + userId) : ("stop " + name));
5776
5777        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5778            if (!doit) {
5779                return true;
5780            }
5781            didSomething = true;
5782        }
5783
5784        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5785            if (!doit) {
5786                return true;
5787            }
5788            didSomething = true;
5789        }
5790
5791        if (name == null) {
5792            // Remove all sticky broadcasts from this user.
5793            mStickyBroadcasts.remove(userId);
5794        }
5795
5796        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5797        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5798                userId, providers)) {
5799            if (!doit) {
5800                return true;
5801            }
5802            didSomething = true;
5803        }
5804        N = providers.size();
5805        for (i=0; i<N; i++) {
5806            removeDyingProviderLocked(null, providers.get(i), true);
5807        }
5808
5809        // Remove transient permissions granted from/to this package/user
5810        removeUriPermissionsForPackageLocked(name, userId, false);
5811
5812        if (name == null || uninstalling) {
5813            // Remove pending intents.  For now we only do this when force
5814            // stopping users, because we have some problems when doing this
5815            // for packages -- app widgets are not currently cleaned up for
5816            // such packages, so they can be left with bad pending intents.
5817            if (mIntentSenderRecords.size() > 0) {
5818                Iterator<WeakReference<PendingIntentRecord>> it
5819                        = mIntentSenderRecords.values().iterator();
5820                while (it.hasNext()) {
5821                    WeakReference<PendingIntentRecord> wpir = it.next();
5822                    if (wpir == null) {
5823                        it.remove();
5824                        continue;
5825                    }
5826                    PendingIntentRecord pir = wpir.get();
5827                    if (pir == null) {
5828                        it.remove();
5829                        continue;
5830                    }
5831                    if (name == null) {
5832                        // Stopping user, remove all objects for the user.
5833                        if (pir.key.userId != userId) {
5834                            // Not the same user, skip it.
5835                            continue;
5836                        }
5837                    } else {
5838                        if (UserHandle.getAppId(pir.uid) != appId) {
5839                            // Different app id, skip it.
5840                            continue;
5841                        }
5842                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5843                            // Different user, skip it.
5844                            continue;
5845                        }
5846                        if (!pir.key.packageName.equals(name)) {
5847                            // Different package, skip it.
5848                            continue;
5849                        }
5850                    }
5851                    if (!doit) {
5852                        return true;
5853                    }
5854                    didSomething = true;
5855                    it.remove();
5856                    pir.canceled = true;
5857                    if (pir.key.activity != null) {
5858                        pir.key.activity.pendingResults.remove(pir.ref);
5859                    }
5860                }
5861            }
5862        }
5863
5864        if (doit) {
5865            if (purgeCache && name != null) {
5866                AttributeCache ac = AttributeCache.instance();
5867                if (ac != null) {
5868                    ac.removePackage(name);
5869                }
5870            }
5871            if (mBooted) {
5872                mStackSupervisor.resumeTopActivitiesLocked();
5873                mStackSupervisor.scheduleIdleLocked();
5874            }
5875        }
5876
5877        return didSomething;
5878    }
5879
5880    private final boolean removeProcessLocked(ProcessRecord app,
5881            boolean callerWillRestart, boolean allowRestart, String reason) {
5882        final String name = app.processName;
5883        final int uid = app.uid;
5884        if (DEBUG_PROCESSES) Slog.d(
5885            TAG, "Force removing proc " + app.toShortString() + " (" + name
5886            + "/" + uid + ")");
5887
5888        mProcessNames.remove(name, uid);
5889        mIsolatedProcesses.remove(app.uid);
5890        if (mHeavyWeightProcess == app) {
5891            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5892                    mHeavyWeightProcess.userId, 0));
5893            mHeavyWeightProcess = null;
5894        }
5895        boolean needRestart = false;
5896        if (app.pid > 0 && app.pid != MY_PID) {
5897            int pid = app.pid;
5898            synchronized (mPidsSelfLocked) {
5899                mPidsSelfLocked.remove(pid);
5900                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5901            }
5902            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5903            if (app.isolated) {
5904                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5905            }
5906            app.kill(reason, true);
5907            handleAppDiedLocked(app, true, allowRestart);
5908            removeLruProcessLocked(app);
5909
5910            if (app.persistent && !app.isolated) {
5911                if (!callerWillRestart) {
5912                    addAppLocked(app.info, false, null /* ABI override */);
5913                } else {
5914                    needRestart = true;
5915                }
5916            }
5917        } else {
5918            mRemovedProcesses.add(app);
5919        }
5920
5921        return needRestart;
5922    }
5923
5924    private final void processStartTimedOutLocked(ProcessRecord app) {
5925        final int pid = app.pid;
5926        boolean gone = false;
5927        synchronized (mPidsSelfLocked) {
5928            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5929            if (knownApp != null && knownApp.thread == null) {
5930                mPidsSelfLocked.remove(pid);
5931                gone = true;
5932            }
5933        }
5934
5935        if (gone) {
5936            Slog.w(TAG, "Process " + app + " failed to attach");
5937            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5938                    pid, app.uid, app.processName);
5939            mProcessNames.remove(app.processName, app.uid);
5940            mIsolatedProcesses.remove(app.uid);
5941            if (mHeavyWeightProcess == app) {
5942                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5943                        mHeavyWeightProcess.userId, 0));
5944                mHeavyWeightProcess = null;
5945            }
5946            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5947            if (app.isolated) {
5948                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5949            }
5950            // Take care of any launching providers waiting for this process.
5951            checkAppInLaunchingProvidersLocked(app, true);
5952            // Take care of any services that are waiting for the process.
5953            mServices.processStartTimedOutLocked(app);
5954            app.kill("start timeout", true);
5955            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5956                Slog.w(TAG, "Unattached app died before backup, skipping");
5957                try {
5958                    IBackupManager bm = IBackupManager.Stub.asInterface(
5959                            ServiceManager.getService(Context.BACKUP_SERVICE));
5960                    bm.agentDisconnected(app.info.packageName);
5961                } catch (RemoteException e) {
5962                    // Can't happen; the backup manager is local
5963                }
5964            }
5965            if (isPendingBroadcastProcessLocked(pid)) {
5966                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5967                skipPendingBroadcastLocked(pid);
5968            }
5969        } else {
5970            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5971        }
5972    }
5973
5974    private final boolean attachApplicationLocked(IApplicationThread thread,
5975            int pid) {
5976
5977        // Find the application record that is being attached...  either via
5978        // the pid if we are running in multiple processes, or just pull the
5979        // next app record if we are emulating process with anonymous threads.
5980        ProcessRecord app;
5981        if (pid != MY_PID && pid >= 0) {
5982            synchronized (mPidsSelfLocked) {
5983                app = mPidsSelfLocked.get(pid);
5984            }
5985        } else {
5986            app = null;
5987        }
5988
5989        if (app == null) {
5990            Slog.w(TAG, "No pending application record for pid " + pid
5991                    + " (IApplicationThread " + thread + "); dropping process");
5992            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5993            if (pid > 0 && pid != MY_PID) {
5994                Process.killProcessQuiet(pid);
5995                //TODO: Process.killProcessGroup(app.info.uid, pid);
5996            } else {
5997                try {
5998                    thread.scheduleExit();
5999                } catch (Exception e) {
6000                    // Ignore exceptions.
6001                }
6002            }
6003            return false;
6004        }
6005
6006        // If this application record is still attached to a previous
6007        // process, clean it up now.
6008        if (app.thread != null) {
6009            handleAppDiedLocked(app, true, true);
6010        }
6011
6012        // Tell the process all about itself.
6013
6014        if (localLOGV) Slog.v(
6015                TAG, "Binding process pid " + pid + " to record " + app);
6016
6017        final String processName = app.processName;
6018        try {
6019            AppDeathRecipient adr = new AppDeathRecipient(
6020                    app, pid, thread);
6021            thread.asBinder().linkToDeath(adr, 0);
6022            app.deathRecipient = adr;
6023        } catch (RemoteException e) {
6024            app.resetPackageList(mProcessStats);
6025            startProcessLocked(app, "link fail", processName);
6026            return false;
6027        }
6028
6029        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6030
6031        app.makeActive(thread, mProcessStats);
6032        app.curAdj = app.setAdj = -100;
6033        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6034        app.forcingToForeground = null;
6035        updateProcessForegroundLocked(app, false, false);
6036        app.hasShownUi = false;
6037        app.debugging = false;
6038        app.cached = false;
6039
6040        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6041
6042        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6043        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6044
6045        if (!normalMode) {
6046            Slog.i(TAG, "Launching preboot mode app: " + app);
6047        }
6048
6049        if (localLOGV) Slog.v(
6050            TAG, "New app record " + app
6051            + " thread=" + thread.asBinder() + " pid=" + pid);
6052        try {
6053            int testMode = IApplicationThread.DEBUG_OFF;
6054            if (mDebugApp != null && mDebugApp.equals(processName)) {
6055                testMode = mWaitForDebugger
6056                    ? IApplicationThread.DEBUG_WAIT
6057                    : IApplicationThread.DEBUG_ON;
6058                app.debugging = true;
6059                if (mDebugTransient) {
6060                    mDebugApp = mOrigDebugApp;
6061                    mWaitForDebugger = mOrigWaitForDebugger;
6062                }
6063            }
6064            String profileFile = app.instrumentationProfileFile;
6065            ParcelFileDescriptor profileFd = null;
6066            int samplingInterval = 0;
6067            boolean profileAutoStop = false;
6068            if (mProfileApp != null && mProfileApp.equals(processName)) {
6069                mProfileProc = app;
6070                profileFile = mProfileFile;
6071                profileFd = mProfileFd;
6072                samplingInterval = mSamplingInterval;
6073                profileAutoStop = mAutoStopProfiler;
6074            }
6075            boolean enableOpenGlTrace = false;
6076            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6077                enableOpenGlTrace = true;
6078                mOpenGlTraceApp = null;
6079            }
6080
6081            // If the app is being launched for restore or full backup, set it up specially
6082            boolean isRestrictedBackupMode = false;
6083            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6084                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6085                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6086                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6087            }
6088
6089            ensurePackageDexOpt(app.instrumentationInfo != null
6090                    ? app.instrumentationInfo.packageName
6091                    : app.info.packageName);
6092            if (app.instrumentationClass != null) {
6093                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6094            }
6095            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6096                    + processName + " with config " + mConfiguration);
6097            ApplicationInfo appInfo = app.instrumentationInfo != null
6098                    ? app.instrumentationInfo : app.info;
6099            app.compat = compatibilityInfoForPackageLocked(appInfo);
6100            if (profileFd != null) {
6101                profileFd = profileFd.dup();
6102            }
6103            ProfilerInfo profilerInfo = profileFile == null ? null
6104                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6105            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6106                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6107                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6108                    isRestrictedBackupMode || !normalMode, app.persistent,
6109                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6110                    mCoreSettingsObserver.getCoreSettingsLocked());
6111            updateLruProcessLocked(app, false, null);
6112            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6113        } catch (Exception e) {
6114            // todo: Yikes!  What should we do?  For now we will try to
6115            // start another process, but that could easily get us in
6116            // an infinite loop of restarting processes...
6117            Slog.w(TAG, "Exception thrown during bind!", e);
6118
6119            app.resetPackageList(mProcessStats);
6120            app.unlinkDeathRecipient();
6121            startProcessLocked(app, "bind fail", processName);
6122            return false;
6123        }
6124
6125        // Remove this record from the list of starting applications.
6126        mPersistentStartingProcesses.remove(app);
6127        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6128                "Attach application locked removing on hold: " + app);
6129        mProcessesOnHold.remove(app);
6130
6131        boolean badApp = false;
6132        boolean didSomething = false;
6133
6134        // See if the top visible activity is waiting to run in this process...
6135        if (normalMode) {
6136            try {
6137                if (mStackSupervisor.attachApplicationLocked(app)) {
6138                    didSomething = true;
6139                }
6140            } catch (Exception e) {
6141                badApp = true;
6142            }
6143        }
6144
6145        // Find any services that should be running in this process...
6146        if (!badApp) {
6147            try {
6148                didSomething |= mServices.attachApplicationLocked(app, processName);
6149            } catch (Exception e) {
6150                badApp = true;
6151            }
6152        }
6153
6154        // Check if a next-broadcast receiver is in this process...
6155        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6156            try {
6157                didSomething |= sendPendingBroadcastsLocked(app);
6158            } catch (Exception e) {
6159                // If the app died trying to launch the receiver we declare it 'bad'
6160                badApp = true;
6161            }
6162        }
6163
6164        // Check whether the next backup agent is in this process...
6165        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6166            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6167            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6168            try {
6169                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6170                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6171                        mBackupTarget.backupMode);
6172            } catch (Exception e) {
6173                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6174                e.printStackTrace();
6175            }
6176        }
6177
6178        if (badApp) {
6179            // todo: Also need to kill application to deal with all
6180            // kinds of exceptions.
6181            handleAppDiedLocked(app, false, true);
6182            return false;
6183        }
6184
6185        if (!didSomething) {
6186            updateOomAdjLocked();
6187        }
6188
6189        return true;
6190    }
6191
6192    @Override
6193    public final void attachApplication(IApplicationThread thread) {
6194        synchronized (this) {
6195            int callingPid = Binder.getCallingPid();
6196            final long origId = Binder.clearCallingIdentity();
6197            attachApplicationLocked(thread, callingPid);
6198            Binder.restoreCallingIdentity(origId);
6199        }
6200    }
6201
6202    @Override
6203    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6204        final long origId = Binder.clearCallingIdentity();
6205        synchronized (this) {
6206            ActivityStack stack = ActivityRecord.getStackLocked(token);
6207            if (stack != null) {
6208                ActivityRecord r =
6209                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6210                if (stopProfiling) {
6211                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6212                        try {
6213                            mProfileFd.close();
6214                        } catch (IOException e) {
6215                        }
6216                        clearProfilerLocked();
6217                    }
6218                }
6219            }
6220        }
6221        Binder.restoreCallingIdentity(origId);
6222    }
6223
6224    void postEnableScreenAfterBootLocked() {
6225        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6226    }
6227
6228    void enableScreenAfterBoot() {
6229        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6230                SystemClock.uptimeMillis());
6231        mWindowManager.enableScreenAfterBoot();
6232
6233        synchronized (this) {
6234            updateEventDispatchingLocked();
6235        }
6236    }
6237
6238    @Override
6239    public void showBootMessage(final CharSequence msg, final boolean always) {
6240        enforceNotIsolatedCaller("showBootMessage");
6241        mWindowManager.showBootMessage(msg, always);
6242    }
6243
6244    @Override
6245    public void keyguardWaitingForActivityDrawn() {
6246        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6247        final long token = Binder.clearCallingIdentity();
6248        try {
6249            synchronized (this) {
6250                if (DEBUG_LOCKSCREEN) logLockScreen("");
6251                mWindowManager.keyguardWaitingForActivityDrawn();
6252                mKeyguardWaitingForDraw = true;
6253            }
6254        } finally {
6255            Binder.restoreCallingIdentity(token);
6256        }
6257    }
6258
6259    final void finishBooting() {
6260        synchronized (this) {
6261            if (!mBootAnimationComplete) {
6262                mCallFinishBooting = true;
6263                return;
6264            }
6265            mCallFinishBooting = false;
6266        }
6267
6268        // Register receivers to handle package update events
6269        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6270
6271        // Let system services know.
6272        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6273
6274        synchronized (this) {
6275            // Ensure that any processes we had put on hold are now started
6276            // up.
6277            final int NP = mProcessesOnHold.size();
6278            if (NP > 0) {
6279                ArrayList<ProcessRecord> procs =
6280                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6281                for (int ip=0; ip<NP; ip++) {
6282                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6283                            + procs.get(ip));
6284                    startProcessLocked(procs.get(ip), "on-hold", null);
6285                }
6286            }
6287
6288            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6289                // Start looking for apps that are abusing wake locks.
6290                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6291                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6292                // Tell anyone interested that we are done booting!
6293                SystemProperties.set("sys.boot_completed", "1");
6294                SystemProperties.set("dev.bootcomplete", "1");
6295                for (int i=0; i<mStartedUsers.size(); i++) {
6296                    UserStartedState uss = mStartedUsers.valueAt(i);
6297                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6298                        uss.mState = UserStartedState.STATE_RUNNING;
6299                        final int userId = mStartedUsers.keyAt(i);
6300                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6301                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6302                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6303                        broadcastIntentLocked(null, null, intent, null,
6304                                new IIntentReceiver.Stub() {
6305                                    @Override
6306                                    public void performReceive(Intent intent, int resultCode,
6307                                            String data, Bundle extras, boolean ordered,
6308                                            boolean sticky, int sendingUser) {
6309                                        synchronized (ActivityManagerService.this) {
6310                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6311                                                    true, false);
6312                                        }
6313                                    }
6314                                },
6315                                0, null, null,
6316                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6317                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6318                                userId);
6319                    }
6320                }
6321                scheduleStartProfilesLocked();
6322            }
6323        }
6324    }
6325
6326    @Override
6327    public void bootAnimationComplete() {
6328        final boolean callFinishBooting;
6329        synchronized (this) {
6330            callFinishBooting = mCallFinishBooting;
6331            mBootAnimationComplete = true;
6332        }
6333        if (callFinishBooting) {
6334            finishBooting();
6335        }
6336    }
6337
6338    final void ensureBootCompleted() {
6339        boolean booting;
6340        boolean enableScreen;
6341        synchronized (this) {
6342            booting = mBooting;
6343            mBooting = false;
6344            enableScreen = !mBooted;
6345            mBooted = true;
6346        }
6347
6348        if (booting) {
6349            finishBooting();
6350        }
6351
6352        if (enableScreen) {
6353            enableScreenAfterBoot();
6354        }
6355    }
6356
6357    @Override
6358    public final void activityResumed(IBinder token) {
6359        final long origId = Binder.clearCallingIdentity();
6360        synchronized(this) {
6361            ActivityStack stack = ActivityRecord.getStackLocked(token);
6362            if (stack != null) {
6363                ActivityRecord.activityResumedLocked(token);
6364            }
6365        }
6366        Binder.restoreCallingIdentity(origId);
6367    }
6368
6369    @Override
6370    public final void activityPaused(IBinder token) {
6371        final long origId = Binder.clearCallingIdentity();
6372        synchronized(this) {
6373            ActivityStack stack = ActivityRecord.getStackLocked(token);
6374            if (stack != null) {
6375                stack.activityPausedLocked(token, false);
6376            }
6377        }
6378        Binder.restoreCallingIdentity(origId);
6379    }
6380
6381    @Override
6382    public final void activityStopped(IBinder token, Bundle icicle,
6383            PersistableBundle persistentState, CharSequence description) {
6384        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6385
6386        // Refuse possible leaked file descriptors
6387        if (icicle != null && icicle.hasFileDescriptors()) {
6388            throw new IllegalArgumentException("File descriptors passed in Bundle");
6389        }
6390
6391        final long origId = Binder.clearCallingIdentity();
6392
6393        synchronized (this) {
6394            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6395            if (r != null) {
6396                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6397            }
6398        }
6399
6400        trimApplications();
6401
6402        Binder.restoreCallingIdentity(origId);
6403    }
6404
6405    @Override
6406    public final void activityDestroyed(IBinder token) {
6407        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6408        synchronized (this) {
6409            ActivityStack stack = ActivityRecord.getStackLocked(token);
6410            if (stack != null) {
6411                stack.activityDestroyedLocked(token);
6412            }
6413        }
6414    }
6415
6416    @Override
6417    public final void backgroundResourcesReleased(IBinder token) {
6418        final long origId = Binder.clearCallingIdentity();
6419        try {
6420            synchronized (this) {
6421                ActivityStack stack = ActivityRecord.getStackLocked(token);
6422                if (stack != null) {
6423                    stack.backgroundResourcesReleased(token);
6424                }
6425            }
6426        } finally {
6427            Binder.restoreCallingIdentity(origId);
6428        }
6429    }
6430
6431    @Override
6432    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6433        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6434    }
6435
6436    @Override
6437    public final void notifyEnterAnimationComplete(IBinder token) {
6438        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6439    }
6440
6441    @Override
6442    public String getCallingPackage(IBinder token) {
6443        synchronized (this) {
6444            ActivityRecord r = getCallingRecordLocked(token);
6445            return r != null ? r.info.packageName : null;
6446        }
6447    }
6448
6449    @Override
6450    public ComponentName getCallingActivity(IBinder token) {
6451        synchronized (this) {
6452            ActivityRecord r = getCallingRecordLocked(token);
6453            return r != null ? r.intent.getComponent() : null;
6454        }
6455    }
6456
6457    private ActivityRecord getCallingRecordLocked(IBinder token) {
6458        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6459        if (r == null) {
6460            return null;
6461        }
6462        return r.resultTo;
6463    }
6464
6465    @Override
6466    public ComponentName getActivityClassForToken(IBinder token) {
6467        synchronized(this) {
6468            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6469            if (r == null) {
6470                return null;
6471            }
6472            return r.intent.getComponent();
6473        }
6474    }
6475
6476    @Override
6477    public String getPackageForToken(IBinder token) {
6478        synchronized(this) {
6479            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6480            if (r == null) {
6481                return null;
6482            }
6483            return r.packageName;
6484        }
6485    }
6486
6487    @Override
6488    public IIntentSender getIntentSender(int type,
6489            String packageName, IBinder token, String resultWho,
6490            int requestCode, Intent[] intents, String[] resolvedTypes,
6491            int flags, Bundle options, int userId) {
6492        enforceNotIsolatedCaller("getIntentSender");
6493        // Refuse possible leaked file descriptors
6494        if (intents != null) {
6495            if (intents.length < 1) {
6496                throw new IllegalArgumentException("Intents array length must be >= 1");
6497            }
6498            for (int i=0; i<intents.length; i++) {
6499                Intent intent = intents[i];
6500                if (intent != null) {
6501                    if (intent.hasFileDescriptors()) {
6502                        throw new IllegalArgumentException("File descriptors passed in Intent");
6503                    }
6504                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6505                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6506                        throw new IllegalArgumentException(
6507                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6508                    }
6509                    intents[i] = new Intent(intent);
6510                }
6511            }
6512            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6513                throw new IllegalArgumentException(
6514                        "Intent array length does not match resolvedTypes length");
6515            }
6516        }
6517        if (options != null) {
6518            if (options.hasFileDescriptors()) {
6519                throw new IllegalArgumentException("File descriptors passed in options");
6520            }
6521        }
6522
6523        synchronized(this) {
6524            int callingUid = Binder.getCallingUid();
6525            int origUserId = userId;
6526            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6527                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6528                    ALLOW_NON_FULL, "getIntentSender", null);
6529            if (origUserId == UserHandle.USER_CURRENT) {
6530                // We don't want to evaluate this until the pending intent is
6531                // actually executed.  However, we do want to always do the
6532                // security checking for it above.
6533                userId = UserHandle.USER_CURRENT;
6534            }
6535            try {
6536                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6537                    int uid = AppGlobals.getPackageManager()
6538                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6539                    if (!UserHandle.isSameApp(callingUid, uid)) {
6540                        String msg = "Permission Denial: getIntentSender() from pid="
6541                            + Binder.getCallingPid()
6542                            + ", uid=" + Binder.getCallingUid()
6543                            + ", (need uid=" + uid + ")"
6544                            + " is not allowed to send as package " + packageName;
6545                        Slog.w(TAG, msg);
6546                        throw new SecurityException(msg);
6547                    }
6548                }
6549
6550                return getIntentSenderLocked(type, packageName, callingUid, userId,
6551                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6552
6553            } catch (RemoteException e) {
6554                throw new SecurityException(e);
6555            }
6556        }
6557    }
6558
6559    IIntentSender getIntentSenderLocked(int type, String packageName,
6560            int callingUid, int userId, IBinder token, String resultWho,
6561            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6562            Bundle options) {
6563        if (DEBUG_MU)
6564            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6565        ActivityRecord activity = null;
6566        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6567            activity = ActivityRecord.isInStackLocked(token);
6568            if (activity == null) {
6569                return null;
6570            }
6571            if (activity.finishing) {
6572                return null;
6573            }
6574        }
6575
6576        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6577        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6578        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6579        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6580                |PendingIntent.FLAG_UPDATE_CURRENT);
6581
6582        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6583                type, packageName, activity, resultWho,
6584                requestCode, intents, resolvedTypes, flags, options, userId);
6585        WeakReference<PendingIntentRecord> ref;
6586        ref = mIntentSenderRecords.get(key);
6587        PendingIntentRecord rec = ref != null ? ref.get() : null;
6588        if (rec != null) {
6589            if (!cancelCurrent) {
6590                if (updateCurrent) {
6591                    if (rec.key.requestIntent != null) {
6592                        rec.key.requestIntent.replaceExtras(intents != null ?
6593                                intents[intents.length - 1] : null);
6594                    }
6595                    if (intents != null) {
6596                        intents[intents.length-1] = rec.key.requestIntent;
6597                        rec.key.allIntents = intents;
6598                        rec.key.allResolvedTypes = resolvedTypes;
6599                    } else {
6600                        rec.key.allIntents = null;
6601                        rec.key.allResolvedTypes = null;
6602                    }
6603                }
6604                return rec;
6605            }
6606            rec.canceled = true;
6607            mIntentSenderRecords.remove(key);
6608        }
6609        if (noCreate) {
6610            return rec;
6611        }
6612        rec = new PendingIntentRecord(this, key, callingUid);
6613        mIntentSenderRecords.put(key, rec.ref);
6614        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6615            if (activity.pendingResults == null) {
6616                activity.pendingResults
6617                        = new HashSet<WeakReference<PendingIntentRecord>>();
6618            }
6619            activity.pendingResults.add(rec.ref);
6620        }
6621        return rec;
6622    }
6623
6624    @Override
6625    public void cancelIntentSender(IIntentSender sender) {
6626        if (!(sender instanceof PendingIntentRecord)) {
6627            return;
6628        }
6629        synchronized(this) {
6630            PendingIntentRecord rec = (PendingIntentRecord)sender;
6631            try {
6632                int uid = AppGlobals.getPackageManager()
6633                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6634                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6635                    String msg = "Permission Denial: cancelIntentSender() from pid="
6636                        + Binder.getCallingPid()
6637                        + ", uid=" + Binder.getCallingUid()
6638                        + " is not allowed to cancel packges "
6639                        + rec.key.packageName;
6640                    Slog.w(TAG, msg);
6641                    throw new SecurityException(msg);
6642                }
6643            } catch (RemoteException e) {
6644                throw new SecurityException(e);
6645            }
6646            cancelIntentSenderLocked(rec, true);
6647        }
6648    }
6649
6650    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6651        rec.canceled = true;
6652        mIntentSenderRecords.remove(rec.key);
6653        if (cleanActivity && rec.key.activity != null) {
6654            rec.key.activity.pendingResults.remove(rec.ref);
6655        }
6656    }
6657
6658    @Override
6659    public String getPackageForIntentSender(IIntentSender pendingResult) {
6660        if (!(pendingResult instanceof PendingIntentRecord)) {
6661            return null;
6662        }
6663        try {
6664            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6665            return res.key.packageName;
6666        } catch (ClassCastException e) {
6667        }
6668        return null;
6669    }
6670
6671    @Override
6672    public int getUidForIntentSender(IIntentSender sender) {
6673        if (sender instanceof PendingIntentRecord) {
6674            try {
6675                PendingIntentRecord res = (PendingIntentRecord)sender;
6676                return res.uid;
6677            } catch (ClassCastException e) {
6678            }
6679        }
6680        return -1;
6681    }
6682
6683    @Override
6684    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6685        if (!(pendingResult instanceof PendingIntentRecord)) {
6686            return false;
6687        }
6688        try {
6689            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6690            if (res.key.allIntents == null) {
6691                return false;
6692            }
6693            for (int i=0; i<res.key.allIntents.length; i++) {
6694                Intent intent = res.key.allIntents[i];
6695                if (intent.getPackage() != null && intent.getComponent() != null) {
6696                    return false;
6697                }
6698            }
6699            return true;
6700        } catch (ClassCastException e) {
6701        }
6702        return false;
6703    }
6704
6705    @Override
6706    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6707        if (!(pendingResult instanceof PendingIntentRecord)) {
6708            return false;
6709        }
6710        try {
6711            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6712            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6713                return true;
6714            }
6715            return false;
6716        } catch (ClassCastException e) {
6717        }
6718        return false;
6719    }
6720
6721    @Override
6722    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6723        if (!(pendingResult instanceof PendingIntentRecord)) {
6724            return null;
6725        }
6726        try {
6727            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6728            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6729        } catch (ClassCastException e) {
6730        }
6731        return null;
6732    }
6733
6734    @Override
6735    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6736        if (!(pendingResult instanceof PendingIntentRecord)) {
6737            return null;
6738        }
6739        try {
6740            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6741            Intent intent = res.key.requestIntent;
6742            if (intent != null) {
6743                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6744                        || res.lastTagPrefix.equals(prefix))) {
6745                    return res.lastTag;
6746                }
6747                res.lastTagPrefix = prefix;
6748                StringBuilder sb = new StringBuilder(128);
6749                if (prefix != null) {
6750                    sb.append(prefix);
6751                }
6752                if (intent.getAction() != null) {
6753                    sb.append(intent.getAction());
6754                } else if (intent.getComponent() != null) {
6755                    intent.getComponent().appendShortString(sb);
6756                } else {
6757                    sb.append("?");
6758                }
6759                return res.lastTag = sb.toString();
6760            }
6761        } catch (ClassCastException e) {
6762        }
6763        return null;
6764    }
6765
6766    @Override
6767    public void setProcessLimit(int max) {
6768        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6769                "setProcessLimit()");
6770        synchronized (this) {
6771            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6772            mProcessLimitOverride = max;
6773        }
6774        trimApplications();
6775    }
6776
6777    @Override
6778    public int getProcessLimit() {
6779        synchronized (this) {
6780            return mProcessLimitOverride;
6781        }
6782    }
6783
6784    void foregroundTokenDied(ForegroundToken token) {
6785        synchronized (ActivityManagerService.this) {
6786            synchronized (mPidsSelfLocked) {
6787                ForegroundToken cur
6788                    = mForegroundProcesses.get(token.pid);
6789                if (cur != token) {
6790                    return;
6791                }
6792                mForegroundProcesses.remove(token.pid);
6793                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6794                if (pr == null) {
6795                    return;
6796                }
6797                pr.forcingToForeground = null;
6798                updateProcessForegroundLocked(pr, false, false);
6799            }
6800            updateOomAdjLocked();
6801        }
6802    }
6803
6804    @Override
6805    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6806        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6807                "setProcessForeground()");
6808        synchronized(this) {
6809            boolean changed = false;
6810
6811            synchronized (mPidsSelfLocked) {
6812                ProcessRecord pr = mPidsSelfLocked.get(pid);
6813                if (pr == null && isForeground) {
6814                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6815                    return;
6816                }
6817                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6818                if (oldToken != null) {
6819                    oldToken.token.unlinkToDeath(oldToken, 0);
6820                    mForegroundProcesses.remove(pid);
6821                    if (pr != null) {
6822                        pr.forcingToForeground = null;
6823                    }
6824                    changed = true;
6825                }
6826                if (isForeground && token != null) {
6827                    ForegroundToken newToken = new ForegroundToken() {
6828                        @Override
6829                        public void binderDied() {
6830                            foregroundTokenDied(this);
6831                        }
6832                    };
6833                    newToken.pid = pid;
6834                    newToken.token = token;
6835                    try {
6836                        token.linkToDeath(newToken, 0);
6837                        mForegroundProcesses.put(pid, newToken);
6838                        pr.forcingToForeground = token;
6839                        changed = true;
6840                    } catch (RemoteException e) {
6841                        // If the process died while doing this, we will later
6842                        // do the cleanup with the process death link.
6843                    }
6844                }
6845            }
6846
6847            if (changed) {
6848                updateOomAdjLocked();
6849            }
6850        }
6851    }
6852
6853    // =========================================================
6854    // PERMISSIONS
6855    // =========================================================
6856
6857    static class PermissionController extends IPermissionController.Stub {
6858        ActivityManagerService mActivityManagerService;
6859        PermissionController(ActivityManagerService activityManagerService) {
6860            mActivityManagerService = activityManagerService;
6861        }
6862
6863        @Override
6864        public boolean checkPermission(String permission, int pid, int uid) {
6865            return mActivityManagerService.checkPermission(permission, pid,
6866                    uid) == PackageManager.PERMISSION_GRANTED;
6867        }
6868    }
6869
6870    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6871        @Override
6872        public int checkComponentPermission(String permission, int pid, int uid,
6873                int owningUid, boolean exported) {
6874            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6875                    owningUid, exported);
6876        }
6877
6878        @Override
6879        public Object getAMSLock() {
6880            return ActivityManagerService.this;
6881        }
6882    }
6883
6884    /**
6885     * This can be called with or without the global lock held.
6886     */
6887    int checkComponentPermission(String permission, int pid, int uid,
6888            int owningUid, boolean exported) {
6889        // We might be performing an operation on behalf of an indirect binder
6890        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6891        // client identity accordingly before proceeding.
6892        Identity tlsIdentity = sCallerIdentity.get();
6893        if (tlsIdentity != null) {
6894            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6895                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6896            uid = tlsIdentity.uid;
6897            pid = tlsIdentity.pid;
6898        }
6899
6900        if (pid == MY_PID) {
6901            return PackageManager.PERMISSION_GRANTED;
6902        }
6903
6904        return ActivityManager.checkComponentPermission(permission, uid,
6905                owningUid, exported);
6906    }
6907
6908    /**
6909     * As the only public entry point for permissions checking, this method
6910     * can enforce the semantic that requesting a check on a null global
6911     * permission is automatically denied.  (Internally a null permission
6912     * string is used when calling {@link #checkComponentPermission} in cases
6913     * when only uid-based security is needed.)
6914     *
6915     * This can be called with or without the global lock held.
6916     */
6917    @Override
6918    public int checkPermission(String permission, int pid, int uid) {
6919        if (permission == null) {
6920            return PackageManager.PERMISSION_DENIED;
6921        }
6922        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6923    }
6924
6925    /**
6926     * Binder IPC calls go through the public entry point.
6927     * This can be called with or without the global lock held.
6928     */
6929    int checkCallingPermission(String permission) {
6930        return checkPermission(permission,
6931                Binder.getCallingPid(),
6932                UserHandle.getAppId(Binder.getCallingUid()));
6933    }
6934
6935    /**
6936     * This can be called with or without the global lock held.
6937     */
6938    void enforceCallingPermission(String permission, String func) {
6939        if (checkCallingPermission(permission)
6940                == PackageManager.PERMISSION_GRANTED) {
6941            return;
6942        }
6943
6944        String msg = "Permission Denial: " + func + " from pid="
6945                + Binder.getCallingPid()
6946                + ", uid=" + Binder.getCallingUid()
6947                + " requires " + permission;
6948        Slog.w(TAG, msg);
6949        throw new SecurityException(msg);
6950    }
6951
6952    /**
6953     * Determine if UID is holding permissions required to access {@link Uri} in
6954     * the given {@link ProviderInfo}. Final permission checking is always done
6955     * in {@link ContentProvider}.
6956     */
6957    private final boolean checkHoldingPermissionsLocked(
6958            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6959        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6960                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6961        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6962            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6963                    != PERMISSION_GRANTED) {
6964                return false;
6965            }
6966        }
6967        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6968    }
6969
6970    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6971            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6972        if (pi.applicationInfo.uid == uid) {
6973            return true;
6974        } else if (!pi.exported) {
6975            return false;
6976        }
6977
6978        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6979        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6980        try {
6981            // check if target holds top-level <provider> permissions
6982            if (!readMet && pi.readPermission != null && considerUidPermissions
6983                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6984                readMet = true;
6985            }
6986            if (!writeMet && pi.writePermission != null && considerUidPermissions
6987                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6988                writeMet = true;
6989            }
6990
6991            // track if unprotected read/write is allowed; any denied
6992            // <path-permission> below removes this ability
6993            boolean allowDefaultRead = pi.readPermission == null;
6994            boolean allowDefaultWrite = pi.writePermission == null;
6995
6996            // check if target holds any <path-permission> that match uri
6997            final PathPermission[] pps = pi.pathPermissions;
6998            if (pps != null) {
6999                final String path = grantUri.uri.getPath();
7000                int i = pps.length;
7001                while (i > 0 && (!readMet || !writeMet)) {
7002                    i--;
7003                    PathPermission pp = pps[i];
7004                    if (pp.match(path)) {
7005                        if (!readMet) {
7006                            final String pprperm = pp.getReadPermission();
7007                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7008                                    + pprperm + " for " + pp.getPath()
7009                                    + ": match=" + pp.match(path)
7010                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7011                            if (pprperm != null) {
7012                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7013                                        == PERMISSION_GRANTED) {
7014                                    readMet = true;
7015                                } else {
7016                                    allowDefaultRead = false;
7017                                }
7018                            }
7019                        }
7020                        if (!writeMet) {
7021                            final String ppwperm = pp.getWritePermission();
7022                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7023                                    + ppwperm + " for " + pp.getPath()
7024                                    + ": match=" + pp.match(path)
7025                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7026                            if (ppwperm != null) {
7027                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7028                                        == PERMISSION_GRANTED) {
7029                                    writeMet = true;
7030                                } else {
7031                                    allowDefaultWrite = false;
7032                                }
7033                            }
7034                        }
7035                    }
7036                }
7037            }
7038
7039            // grant unprotected <provider> read/write, if not blocked by
7040            // <path-permission> above
7041            if (allowDefaultRead) readMet = true;
7042            if (allowDefaultWrite) writeMet = true;
7043
7044        } catch (RemoteException e) {
7045            return false;
7046        }
7047
7048        return readMet && writeMet;
7049    }
7050
7051    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7052        ProviderInfo pi = null;
7053        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7054        if (cpr != null) {
7055            pi = cpr.info;
7056        } else {
7057            try {
7058                pi = AppGlobals.getPackageManager().resolveContentProvider(
7059                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7060            } catch (RemoteException ex) {
7061            }
7062        }
7063        return pi;
7064    }
7065
7066    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7067        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7068        if (targetUris != null) {
7069            return targetUris.get(grantUri);
7070        }
7071        return null;
7072    }
7073
7074    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7075            String targetPkg, int targetUid, GrantUri grantUri) {
7076        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7077        if (targetUris == null) {
7078            targetUris = Maps.newArrayMap();
7079            mGrantedUriPermissions.put(targetUid, targetUris);
7080        }
7081
7082        UriPermission perm = targetUris.get(grantUri);
7083        if (perm == null) {
7084            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7085            targetUris.put(grantUri, perm);
7086        }
7087
7088        return perm;
7089    }
7090
7091    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7092            final int modeFlags) {
7093        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7094        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7095                : UriPermission.STRENGTH_OWNED;
7096
7097        // Root gets to do everything.
7098        if (uid == 0) {
7099            return true;
7100        }
7101
7102        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7103        if (perms == null) return false;
7104
7105        // First look for exact match
7106        final UriPermission exactPerm = perms.get(grantUri);
7107        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7108            return true;
7109        }
7110
7111        // No exact match, look for prefixes
7112        final int N = perms.size();
7113        for (int i = 0; i < N; i++) {
7114            final UriPermission perm = perms.valueAt(i);
7115            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7116                    && perm.getStrength(modeFlags) >= minStrength) {
7117                return true;
7118            }
7119        }
7120
7121        return false;
7122    }
7123
7124    /**
7125     * @param uri This uri must NOT contain an embedded userId.
7126     * @param userId The userId in which the uri is to be resolved.
7127     */
7128    @Override
7129    public int checkUriPermission(Uri uri, int pid, int uid,
7130            final int modeFlags, int userId) {
7131        enforceNotIsolatedCaller("checkUriPermission");
7132
7133        // Another redirected-binder-call permissions check as in
7134        // {@link checkComponentPermission}.
7135        Identity tlsIdentity = sCallerIdentity.get();
7136        if (tlsIdentity != null) {
7137            uid = tlsIdentity.uid;
7138            pid = tlsIdentity.pid;
7139        }
7140
7141        // Our own process gets to do everything.
7142        if (pid == MY_PID) {
7143            return PackageManager.PERMISSION_GRANTED;
7144        }
7145        synchronized (this) {
7146            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7147                    ? PackageManager.PERMISSION_GRANTED
7148                    : PackageManager.PERMISSION_DENIED;
7149        }
7150    }
7151
7152    /**
7153     * Check if the targetPkg can be granted permission to access uri by
7154     * the callingUid using the given modeFlags.  Throws a security exception
7155     * if callingUid is not allowed to do this.  Returns the uid of the target
7156     * if the URI permission grant should be performed; returns -1 if it is not
7157     * needed (for example targetPkg already has permission to access the URI).
7158     * If you already know the uid of the target, you can supply it in
7159     * lastTargetUid else set that to -1.
7160     */
7161    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7162            final int modeFlags, int lastTargetUid) {
7163        if (!Intent.isAccessUriMode(modeFlags)) {
7164            return -1;
7165        }
7166
7167        if (targetPkg != null) {
7168            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7169                    "Checking grant " + targetPkg + " permission to " + grantUri);
7170        }
7171
7172        final IPackageManager pm = AppGlobals.getPackageManager();
7173
7174        // If this is not a content: uri, we can't do anything with it.
7175        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7176            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7177                    "Can't grant URI permission for non-content URI: " + grantUri);
7178            return -1;
7179        }
7180
7181        final String authority = grantUri.uri.getAuthority();
7182        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7183        if (pi == null) {
7184            Slog.w(TAG, "No content provider found for permission check: " +
7185                    grantUri.uri.toSafeString());
7186            return -1;
7187        }
7188
7189        int targetUid = lastTargetUid;
7190        if (targetUid < 0 && targetPkg != null) {
7191            try {
7192                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7193                if (targetUid < 0) {
7194                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7195                            "Can't grant URI permission no uid for: " + targetPkg);
7196                    return -1;
7197                }
7198            } catch (RemoteException ex) {
7199                return -1;
7200            }
7201        }
7202
7203        if (targetUid >= 0) {
7204            // First...  does the target actually need this permission?
7205            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7206                // No need to grant the target this permission.
7207                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7208                        "Target " + targetPkg + " already has full permission to " + grantUri);
7209                return -1;
7210            }
7211        } else {
7212            // First...  there is no target package, so can anyone access it?
7213            boolean allowed = pi.exported;
7214            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7215                if (pi.readPermission != null) {
7216                    allowed = false;
7217                }
7218            }
7219            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7220                if (pi.writePermission != null) {
7221                    allowed = false;
7222                }
7223            }
7224            if (allowed) {
7225                return -1;
7226            }
7227        }
7228
7229        /* There is a special cross user grant if:
7230         * - The target is on another user.
7231         * - Apps on the current user can access the uri without any uid permissions.
7232         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7233         * grant uri permissions.
7234         */
7235        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7236                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7237                modeFlags, false /*without considering the uid permissions*/);
7238
7239        // Second...  is the provider allowing granting of URI permissions?
7240        if (!specialCrossUserGrant) {
7241            if (!pi.grantUriPermissions) {
7242                throw new SecurityException("Provider " + pi.packageName
7243                        + "/" + pi.name
7244                        + " does not allow granting of Uri permissions (uri "
7245                        + grantUri + ")");
7246            }
7247            if (pi.uriPermissionPatterns != null) {
7248                final int N = pi.uriPermissionPatterns.length;
7249                boolean allowed = false;
7250                for (int i=0; i<N; i++) {
7251                    if (pi.uriPermissionPatterns[i] != null
7252                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7253                        allowed = true;
7254                        break;
7255                    }
7256                }
7257                if (!allowed) {
7258                    throw new SecurityException("Provider " + pi.packageName
7259                            + "/" + pi.name
7260                            + " does not allow granting of permission to path of Uri "
7261                            + grantUri);
7262                }
7263            }
7264        }
7265
7266        // Third...  does the caller itself have permission to access
7267        // this uri?
7268        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7269            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7270                // Require they hold a strong enough Uri permission
7271                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7272                    throw new SecurityException("Uid " + callingUid
7273                            + " does not have permission to uri " + grantUri);
7274                }
7275            }
7276        }
7277        return targetUid;
7278    }
7279
7280    /**
7281     * @param uri This uri must NOT contain an embedded userId.
7282     * @param userId The userId in which the uri is to be resolved.
7283     */
7284    @Override
7285    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7286            final int modeFlags, int userId) {
7287        enforceNotIsolatedCaller("checkGrantUriPermission");
7288        synchronized(this) {
7289            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7290                    new GrantUri(userId, uri, false), modeFlags, -1);
7291        }
7292    }
7293
7294    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7295            final int modeFlags, UriPermissionOwner owner) {
7296        if (!Intent.isAccessUriMode(modeFlags)) {
7297            return;
7298        }
7299
7300        // So here we are: the caller has the assumed permission
7301        // to the uri, and the target doesn't.  Let's now give this to
7302        // the target.
7303
7304        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7305                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7306
7307        final String authority = grantUri.uri.getAuthority();
7308        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7309        if (pi == null) {
7310            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7311            return;
7312        }
7313
7314        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7315            grantUri.prefix = true;
7316        }
7317        final UriPermission perm = findOrCreateUriPermissionLocked(
7318                pi.packageName, targetPkg, targetUid, grantUri);
7319        perm.grantModes(modeFlags, owner);
7320    }
7321
7322    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7323            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7324        if (targetPkg == null) {
7325            throw new NullPointerException("targetPkg");
7326        }
7327        int targetUid;
7328        final IPackageManager pm = AppGlobals.getPackageManager();
7329        try {
7330            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7331        } catch (RemoteException ex) {
7332            return;
7333        }
7334
7335        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7336                targetUid);
7337        if (targetUid < 0) {
7338            return;
7339        }
7340
7341        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7342                owner);
7343    }
7344
7345    static class NeededUriGrants extends ArrayList<GrantUri> {
7346        final String targetPkg;
7347        final int targetUid;
7348        final int flags;
7349
7350        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7351            this.targetPkg = targetPkg;
7352            this.targetUid = targetUid;
7353            this.flags = flags;
7354        }
7355    }
7356
7357    /**
7358     * Like checkGrantUriPermissionLocked, but takes an Intent.
7359     */
7360    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7361            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7362        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7363                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7364                + " clip=" + (intent != null ? intent.getClipData() : null)
7365                + " from " + intent + "; flags=0x"
7366                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7367
7368        if (targetPkg == null) {
7369            throw new NullPointerException("targetPkg");
7370        }
7371
7372        if (intent == null) {
7373            return null;
7374        }
7375        Uri data = intent.getData();
7376        ClipData clip = intent.getClipData();
7377        if (data == null && clip == null) {
7378            return null;
7379        }
7380        // Default userId for uris in the intent (if they don't specify it themselves)
7381        int contentUserHint = intent.getContentUserHint();
7382        if (contentUserHint == UserHandle.USER_CURRENT) {
7383            contentUserHint = UserHandle.getUserId(callingUid);
7384        }
7385        final IPackageManager pm = AppGlobals.getPackageManager();
7386        int targetUid;
7387        if (needed != null) {
7388            targetUid = needed.targetUid;
7389        } else {
7390            try {
7391                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7392            } catch (RemoteException ex) {
7393                return null;
7394            }
7395            if (targetUid < 0) {
7396                if (DEBUG_URI_PERMISSION) {
7397                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7398                            + " on user " + targetUserId);
7399                }
7400                return null;
7401            }
7402        }
7403        if (data != null) {
7404            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7405            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7406                    targetUid);
7407            if (targetUid > 0) {
7408                if (needed == null) {
7409                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7410                }
7411                needed.add(grantUri);
7412            }
7413        }
7414        if (clip != null) {
7415            for (int i=0; i<clip.getItemCount(); i++) {
7416                Uri uri = clip.getItemAt(i).getUri();
7417                if (uri != null) {
7418                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7419                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7420                            targetUid);
7421                    if (targetUid > 0) {
7422                        if (needed == null) {
7423                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7424                        }
7425                        needed.add(grantUri);
7426                    }
7427                } else {
7428                    Intent clipIntent = clip.getItemAt(i).getIntent();
7429                    if (clipIntent != null) {
7430                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7431                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7432                        if (newNeeded != null) {
7433                            needed = newNeeded;
7434                        }
7435                    }
7436                }
7437            }
7438        }
7439
7440        return needed;
7441    }
7442
7443    /**
7444     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7445     */
7446    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7447            UriPermissionOwner owner) {
7448        if (needed != null) {
7449            for (int i=0; i<needed.size(); i++) {
7450                GrantUri grantUri = needed.get(i);
7451                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7452                        grantUri, needed.flags, owner);
7453            }
7454        }
7455    }
7456
7457    void grantUriPermissionFromIntentLocked(int callingUid,
7458            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7459        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7460                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7461        if (needed == null) {
7462            return;
7463        }
7464
7465        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7466    }
7467
7468    /**
7469     * @param uri This uri must NOT contain an embedded userId.
7470     * @param userId The userId in which the uri is to be resolved.
7471     */
7472    @Override
7473    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7474            final int modeFlags, int userId) {
7475        enforceNotIsolatedCaller("grantUriPermission");
7476        GrantUri grantUri = new GrantUri(userId, uri, false);
7477        synchronized(this) {
7478            final ProcessRecord r = getRecordForAppLocked(caller);
7479            if (r == null) {
7480                throw new SecurityException("Unable to find app for caller "
7481                        + caller
7482                        + " when granting permission to uri " + grantUri);
7483            }
7484            if (targetPkg == null) {
7485                throw new IllegalArgumentException("null target");
7486            }
7487            if (grantUri == null) {
7488                throw new IllegalArgumentException("null uri");
7489            }
7490
7491            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7492                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7493                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7494                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7495
7496            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7497                    UserHandle.getUserId(r.uid));
7498        }
7499    }
7500
7501    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7502        if (perm.modeFlags == 0) {
7503            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7504                    perm.targetUid);
7505            if (perms != null) {
7506                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7507                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7508
7509                perms.remove(perm.uri);
7510                if (perms.isEmpty()) {
7511                    mGrantedUriPermissions.remove(perm.targetUid);
7512                }
7513            }
7514        }
7515    }
7516
7517    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7518        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7519
7520        final IPackageManager pm = AppGlobals.getPackageManager();
7521        final String authority = grantUri.uri.getAuthority();
7522        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7523        if (pi == null) {
7524            Slog.w(TAG, "No content provider found for permission revoke: "
7525                    + grantUri.toSafeString());
7526            return;
7527        }
7528
7529        // Does the caller have this permission on the URI?
7530        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7531            // Have they don't have direct access to the URI, then revoke any URI
7532            // permissions that have been granted to them.
7533            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7534            if (perms != null) {
7535                boolean persistChanged = false;
7536                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7537                    final UriPermission perm = it.next();
7538                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7539                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7540                        if (DEBUG_URI_PERMISSION)
7541                            Slog.v(TAG,
7542                                    "Revoking " + perm.targetUid + " permission to " + perm.uri);
7543                        persistChanged |= perm.revokeModes(
7544                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7545                        if (perm.modeFlags == 0) {
7546                            it.remove();
7547                        }
7548                    }
7549                }
7550                if (perms.isEmpty()) {
7551                    mGrantedUriPermissions.remove(callingUid);
7552                }
7553                if (persistChanged) {
7554                    schedulePersistUriGrants();
7555                }
7556            }
7557            return;
7558        }
7559
7560        boolean persistChanged = false;
7561
7562        // Go through all of the permissions and remove any that match.
7563        int N = mGrantedUriPermissions.size();
7564        for (int i = 0; i < N; i++) {
7565            final int targetUid = mGrantedUriPermissions.keyAt(i);
7566            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7567
7568            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7569                final UriPermission perm = it.next();
7570                if (perm.uri.sourceUserId == grantUri.sourceUserId
7571                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7572                    if (DEBUG_URI_PERMISSION)
7573                        Slog.v(TAG,
7574                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7575                    persistChanged |= perm.revokeModes(
7576                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7577                    if (perm.modeFlags == 0) {
7578                        it.remove();
7579                    }
7580                }
7581            }
7582
7583            if (perms.isEmpty()) {
7584                mGrantedUriPermissions.remove(targetUid);
7585                N--;
7586                i--;
7587            }
7588        }
7589
7590        if (persistChanged) {
7591            schedulePersistUriGrants();
7592        }
7593    }
7594
7595    /**
7596     * @param uri This uri must NOT contain an embedded userId.
7597     * @param userId The userId in which the uri is to be resolved.
7598     */
7599    @Override
7600    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7601            int userId) {
7602        enforceNotIsolatedCaller("revokeUriPermission");
7603        synchronized(this) {
7604            final ProcessRecord r = getRecordForAppLocked(caller);
7605            if (r == null) {
7606                throw new SecurityException("Unable to find app for caller "
7607                        + caller
7608                        + " when revoking permission to uri " + uri);
7609            }
7610            if (uri == null) {
7611                Slog.w(TAG, "revokeUriPermission: null uri");
7612                return;
7613            }
7614
7615            if (!Intent.isAccessUriMode(modeFlags)) {
7616                return;
7617            }
7618
7619            final IPackageManager pm = AppGlobals.getPackageManager();
7620            final String authority = uri.getAuthority();
7621            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7622            if (pi == null) {
7623                Slog.w(TAG, "No content provider found for permission revoke: "
7624                        + uri.toSafeString());
7625                return;
7626            }
7627
7628            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7629        }
7630    }
7631
7632    /**
7633     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7634     * given package.
7635     *
7636     * @param packageName Package name to match, or {@code null} to apply to all
7637     *            packages.
7638     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7639     *            to all users.
7640     * @param persistable If persistable grants should be removed.
7641     */
7642    private void removeUriPermissionsForPackageLocked(
7643            String packageName, int userHandle, boolean persistable) {
7644        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7645            throw new IllegalArgumentException("Must narrow by either package or user");
7646        }
7647
7648        boolean persistChanged = false;
7649
7650        int N = mGrantedUriPermissions.size();
7651        for (int i = 0; i < N; i++) {
7652            final int targetUid = mGrantedUriPermissions.keyAt(i);
7653            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7654
7655            // Only inspect grants matching user
7656            if (userHandle == UserHandle.USER_ALL
7657                    || userHandle == UserHandle.getUserId(targetUid)) {
7658                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7659                    final UriPermission perm = it.next();
7660
7661                    // Only inspect grants matching package
7662                    if (packageName == null || perm.sourcePkg.equals(packageName)
7663                            || perm.targetPkg.equals(packageName)) {
7664                        persistChanged |= perm.revokeModes(
7665                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7666
7667                        // Only remove when no modes remain; any persisted grants
7668                        // will keep this alive.
7669                        if (perm.modeFlags == 0) {
7670                            it.remove();
7671                        }
7672                    }
7673                }
7674
7675                if (perms.isEmpty()) {
7676                    mGrantedUriPermissions.remove(targetUid);
7677                    N--;
7678                    i--;
7679                }
7680            }
7681        }
7682
7683        if (persistChanged) {
7684            schedulePersistUriGrants();
7685        }
7686    }
7687
7688    @Override
7689    public IBinder newUriPermissionOwner(String name) {
7690        enforceNotIsolatedCaller("newUriPermissionOwner");
7691        synchronized(this) {
7692            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7693            return owner.getExternalTokenLocked();
7694        }
7695    }
7696
7697    /**
7698     * @param uri This uri must NOT contain an embedded userId.
7699     * @param sourceUserId The userId in which the uri is to be resolved.
7700     * @param targetUserId The userId of the app that receives the grant.
7701     */
7702    @Override
7703    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7704            final int modeFlags, int sourceUserId, int targetUserId) {
7705        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7706                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7707        synchronized(this) {
7708            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7709            if (owner == null) {
7710                throw new IllegalArgumentException("Unknown owner: " + token);
7711            }
7712            if (fromUid != Binder.getCallingUid()) {
7713                if (Binder.getCallingUid() != Process.myUid()) {
7714                    // Only system code can grant URI permissions on behalf
7715                    // of other users.
7716                    throw new SecurityException("nice try");
7717                }
7718            }
7719            if (targetPkg == null) {
7720                throw new IllegalArgumentException("null target");
7721            }
7722            if (uri == null) {
7723                throw new IllegalArgumentException("null uri");
7724            }
7725
7726            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7727                    modeFlags, owner, targetUserId);
7728        }
7729    }
7730
7731    /**
7732     * @param uri This uri must NOT contain an embedded userId.
7733     * @param userId The userId in which the uri is to be resolved.
7734     */
7735    @Override
7736    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7737        synchronized(this) {
7738            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7739            if (owner == null) {
7740                throw new IllegalArgumentException("Unknown owner: " + token);
7741            }
7742
7743            if (uri == null) {
7744                owner.removeUriPermissionsLocked(mode);
7745            } else {
7746                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7747            }
7748        }
7749    }
7750
7751    private void schedulePersistUriGrants() {
7752        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7753            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7754                    10 * DateUtils.SECOND_IN_MILLIS);
7755        }
7756    }
7757
7758    private void writeGrantedUriPermissions() {
7759        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7760
7761        // Snapshot permissions so we can persist without lock
7762        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7763        synchronized (this) {
7764            final int size = mGrantedUriPermissions.size();
7765            for (int i = 0; i < size; i++) {
7766                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7767                for (UriPermission perm : perms.values()) {
7768                    if (perm.persistedModeFlags != 0) {
7769                        persist.add(perm.snapshot());
7770                    }
7771                }
7772            }
7773        }
7774
7775        FileOutputStream fos = null;
7776        try {
7777            fos = mGrantFile.startWrite();
7778
7779            XmlSerializer out = new FastXmlSerializer();
7780            out.setOutput(fos, "utf-8");
7781            out.startDocument(null, true);
7782            out.startTag(null, TAG_URI_GRANTS);
7783            for (UriPermission.Snapshot perm : persist) {
7784                out.startTag(null, TAG_URI_GRANT);
7785                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7786                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7787                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7788                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7789                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7790                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7791                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7792                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7793                out.endTag(null, TAG_URI_GRANT);
7794            }
7795            out.endTag(null, TAG_URI_GRANTS);
7796            out.endDocument();
7797
7798            mGrantFile.finishWrite(fos);
7799        } catch (IOException e) {
7800            if (fos != null) {
7801                mGrantFile.failWrite(fos);
7802            }
7803        }
7804    }
7805
7806    private void readGrantedUriPermissionsLocked() {
7807        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7808
7809        final long now = System.currentTimeMillis();
7810
7811        FileInputStream fis = null;
7812        try {
7813            fis = mGrantFile.openRead();
7814            final XmlPullParser in = Xml.newPullParser();
7815            in.setInput(fis, null);
7816
7817            int type;
7818            while ((type = in.next()) != END_DOCUMENT) {
7819                final String tag = in.getName();
7820                if (type == START_TAG) {
7821                    if (TAG_URI_GRANT.equals(tag)) {
7822                        final int sourceUserId;
7823                        final int targetUserId;
7824                        final int userHandle = readIntAttribute(in,
7825                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7826                        if (userHandle != UserHandle.USER_NULL) {
7827                            // For backwards compatibility.
7828                            sourceUserId = userHandle;
7829                            targetUserId = userHandle;
7830                        } else {
7831                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7832                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7833                        }
7834                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7835                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7836                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7837                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7838                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7839                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7840
7841                        // Sanity check that provider still belongs to source package
7842                        final ProviderInfo pi = getProviderInfoLocked(
7843                                uri.getAuthority(), sourceUserId);
7844                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7845                            int targetUid = -1;
7846                            try {
7847                                targetUid = AppGlobals.getPackageManager()
7848                                        .getPackageUid(targetPkg, targetUserId);
7849                            } catch (RemoteException e) {
7850                            }
7851                            if (targetUid != -1) {
7852                                final UriPermission perm = findOrCreateUriPermissionLocked(
7853                                        sourcePkg, targetPkg, targetUid,
7854                                        new GrantUri(sourceUserId, uri, prefix));
7855                                perm.initPersistedModes(modeFlags, createdTime);
7856                            }
7857                        } else {
7858                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7859                                    + " but instead found " + pi);
7860                        }
7861                    }
7862                }
7863            }
7864        } catch (FileNotFoundException e) {
7865            // Missing grants is okay
7866        } catch (IOException e) {
7867            Log.wtf(TAG, "Failed reading Uri grants", e);
7868        } catch (XmlPullParserException e) {
7869            Log.wtf(TAG, "Failed reading Uri grants", e);
7870        } finally {
7871            IoUtils.closeQuietly(fis);
7872        }
7873    }
7874
7875    /**
7876     * @param uri This uri must NOT contain an embedded userId.
7877     * @param userId The userId in which the uri is to be resolved.
7878     */
7879    @Override
7880    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7881        enforceNotIsolatedCaller("takePersistableUriPermission");
7882
7883        Preconditions.checkFlagsArgument(modeFlags,
7884                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7885
7886        synchronized (this) {
7887            final int callingUid = Binder.getCallingUid();
7888            boolean persistChanged = false;
7889            GrantUri grantUri = new GrantUri(userId, uri, false);
7890
7891            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7892                    new GrantUri(userId, uri, false));
7893            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7894                    new GrantUri(userId, uri, true));
7895
7896            final boolean exactValid = (exactPerm != null)
7897                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7898            final boolean prefixValid = (prefixPerm != null)
7899                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7900
7901            if (!(exactValid || prefixValid)) {
7902                throw new SecurityException("No persistable permission grants found for UID "
7903                        + callingUid + " and Uri " + grantUri.toSafeString());
7904            }
7905
7906            if (exactValid) {
7907                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7908            }
7909            if (prefixValid) {
7910                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7911            }
7912
7913            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7914
7915            if (persistChanged) {
7916                schedulePersistUriGrants();
7917            }
7918        }
7919    }
7920
7921    /**
7922     * @param uri This uri must NOT contain an embedded userId.
7923     * @param userId The userId in which the uri is to be resolved.
7924     */
7925    @Override
7926    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7927        enforceNotIsolatedCaller("releasePersistableUriPermission");
7928
7929        Preconditions.checkFlagsArgument(modeFlags,
7930                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7931
7932        synchronized (this) {
7933            final int callingUid = Binder.getCallingUid();
7934            boolean persistChanged = false;
7935
7936            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7937                    new GrantUri(userId, uri, false));
7938            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7939                    new GrantUri(userId, uri, true));
7940            if (exactPerm == null && prefixPerm == null) {
7941                throw new SecurityException("No permission grants found for UID " + callingUid
7942                        + " and Uri " + uri.toSafeString());
7943            }
7944
7945            if (exactPerm != null) {
7946                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7947                removeUriPermissionIfNeededLocked(exactPerm);
7948            }
7949            if (prefixPerm != null) {
7950                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7951                removeUriPermissionIfNeededLocked(prefixPerm);
7952            }
7953
7954            if (persistChanged) {
7955                schedulePersistUriGrants();
7956            }
7957        }
7958    }
7959
7960    /**
7961     * Prune any older {@link UriPermission} for the given UID until outstanding
7962     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7963     *
7964     * @return if any mutations occured that require persisting.
7965     */
7966    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7967        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7968        if (perms == null) return false;
7969        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7970
7971        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7972        for (UriPermission perm : perms.values()) {
7973            if (perm.persistedModeFlags != 0) {
7974                persisted.add(perm);
7975            }
7976        }
7977
7978        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7979        if (trimCount <= 0) return false;
7980
7981        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7982        for (int i = 0; i < trimCount; i++) {
7983            final UriPermission perm = persisted.get(i);
7984
7985            if (DEBUG_URI_PERMISSION) {
7986                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7987            }
7988
7989            perm.releasePersistableModes(~0);
7990            removeUriPermissionIfNeededLocked(perm);
7991        }
7992
7993        return true;
7994    }
7995
7996    @Override
7997    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7998            String packageName, boolean incoming) {
7999        enforceNotIsolatedCaller("getPersistedUriPermissions");
8000        Preconditions.checkNotNull(packageName, "packageName");
8001
8002        final int callingUid = Binder.getCallingUid();
8003        final IPackageManager pm = AppGlobals.getPackageManager();
8004        try {
8005            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8006            if (packageUid != callingUid) {
8007                throw new SecurityException(
8008                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8009            }
8010        } catch (RemoteException e) {
8011            throw new SecurityException("Failed to verify package name ownership");
8012        }
8013
8014        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8015        synchronized (this) {
8016            if (incoming) {
8017                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8018                        callingUid);
8019                if (perms == null) {
8020                    Slog.w(TAG, "No permission grants found for " + packageName);
8021                } else {
8022                    for (UriPermission perm : perms.values()) {
8023                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8024                            result.add(perm.buildPersistedPublicApiObject());
8025                        }
8026                    }
8027                }
8028            } else {
8029                final int size = mGrantedUriPermissions.size();
8030                for (int i = 0; i < size; i++) {
8031                    final ArrayMap<GrantUri, UriPermission> perms =
8032                            mGrantedUriPermissions.valueAt(i);
8033                    for (UriPermission perm : perms.values()) {
8034                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8035                            result.add(perm.buildPersistedPublicApiObject());
8036                        }
8037                    }
8038                }
8039            }
8040        }
8041        return new ParceledListSlice<android.content.UriPermission>(result);
8042    }
8043
8044    @Override
8045    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8046        synchronized (this) {
8047            ProcessRecord app =
8048                who != null ? getRecordForAppLocked(who) : null;
8049            if (app == null) return;
8050
8051            Message msg = Message.obtain();
8052            msg.what = WAIT_FOR_DEBUGGER_MSG;
8053            msg.obj = app;
8054            msg.arg1 = waiting ? 1 : 0;
8055            mHandler.sendMessage(msg);
8056        }
8057    }
8058
8059    @Override
8060    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8061        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8062        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8063        outInfo.availMem = Process.getFreeMemory();
8064        outInfo.totalMem = Process.getTotalMemory();
8065        outInfo.threshold = homeAppMem;
8066        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8067        outInfo.hiddenAppThreshold = cachedAppMem;
8068        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8069                ProcessList.SERVICE_ADJ);
8070        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8071                ProcessList.VISIBLE_APP_ADJ);
8072        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8073                ProcessList.FOREGROUND_APP_ADJ);
8074    }
8075
8076    // =========================================================
8077    // TASK MANAGEMENT
8078    // =========================================================
8079
8080    @Override
8081    public List<IAppTask> getAppTasks(String callingPackage) {
8082        int callingUid = Binder.getCallingUid();
8083        long ident = Binder.clearCallingIdentity();
8084
8085        synchronized(this) {
8086            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8087            try {
8088                if (localLOGV) Slog.v(TAG, "getAppTasks");
8089
8090                final int N = mRecentTasks.size();
8091                for (int i = 0; i < N; i++) {
8092                    TaskRecord tr = mRecentTasks.get(i);
8093                    // Skip tasks that do not match the caller.  We don't need to verify
8094                    // callingPackage, because we are also limiting to callingUid and know
8095                    // that will limit to the correct security sandbox.
8096                    if (tr.effectiveUid != callingUid) {
8097                        continue;
8098                    }
8099                    Intent intent = tr.getBaseIntent();
8100                    if (intent == null ||
8101                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8102                        continue;
8103                    }
8104                    ActivityManager.RecentTaskInfo taskInfo =
8105                            createRecentTaskInfoFromTaskRecord(tr);
8106                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8107                    list.add(taskImpl);
8108                }
8109            } finally {
8110                Binder.restoreCallingIdentity(ident);
8111            }
8112            return list;
8113        }
8114    }
8115
8116    @Override
8117    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8118        final int callingUid = Binder.getCallingUid();
8119        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8120
8121        synchronized(this) {
8122            if (localLOGV) Slog.v(
8123                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8124
8125            final boolean allowed = checkCallingPermission(
8126                    android.Manifest.permission.GET_TASKS)
8127                    == PackageManager.PERMISSION_GRANTED;
8128            if (!allowed) {
8129                Slog.w(TAG, "getTasks: caller " + callingUid
8130                        + " does not hold GET_TASKS; limiting output");
8131            }
8132
8133            // TODO: Improve with MRU list from all ActivityStacks.
8134            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8135        }
8136
8137        return list;
8138    }
8139
8140    TaskRecord getMostRecentTask() {
8141        return mRecentTasks.get(0);
8142    }
8143
8144    /**
8145     * Creates a new RecentTaskInfo from a TaskRecord.
8146     */
8147    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8148        // Update the task description to reflect any changes in the task stack
8149        tr.updateTaskDescription();
8150
8151        // Compose the recent task info
8152        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8153        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8154        rti.persistentId = tr.taskId;
8155        rti.baseIntent = new Intent(tr.getBaseIntent());
8156        rti.origActivity = tr.origActivity;
8157        rti.description = tr.lastDescription;
8158        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8159        rti.userId = tr.userId;
8160        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8161        rti.firstActiveTime = tr.firstActiveTime;
8162        rti.lastActiveTime = tr.lastActiveTime;
8163        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8164        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8165        return rti;
8166    }
8167
8168    @Override
8169    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8170        final int callingUid = Binder.getCallingUid();
8171        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8172                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8173
8174        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8175        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8176        synchronized (this) {
8177            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8178                    == PackageManager.PERMISSION_GRANTED;
8179            if (!allowed) {
8180                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8181                        + " does not hold GET_TASKS; limiting output");
8182            }
8183            final boolean detailed = checkCallingPermission(
8184                    android.Manifest.permission.GET_DETAILED_TASKS)
8185                    == PackageManager.PERMISSION_GRANTED;
8186
8187            final int N = mRecentTasks.size();
8188            ArrayList<ActivityManager.RecentTaskInfo> res
8189                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8190                            maxNum < N ? maxNum : N);
8191
8192            final Set<Integer> includedUsers;
8193            if (includeProfiles) {
8194                includedUsers = getProfileIdsLocked(userId);
8195            } else {
8196                includedUsers = new HashSet<Integer>();
8197            }
8198            includedUsers.add(Integer.valueOf(userId));
8199
8200            for (int i=0; i<N && maxNum > 0; i++) {
8201                TaskRecord tr = mRecentTasks.get(i);
8202                // Only add calling user or related users recent tasks
8203                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8204                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8205                    continue;
8206                }
8207
8208                // Return the entry if desired by the caller.  We always return
8209                // the first entry, because callers always expect this to be the
8210                // foreground app.  We may filter others if the caller has
8211                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8212                // we should exclude the entry.
8213
8214                if (i == 0
8215                        || withExcluded
8216                        || (tr.intent == null)
8217                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8218                                == 0)) {
8219                    if (!allowed) {
8220                        // If the caller doesn't have the GET_TASKS permission, then only
8221                        // allow them to see a small subset of tasks -- their own and home.
8222                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8223                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8224                            continue;
8225                        }
8226                    }
8227                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8228                        if (tr.stack != null && tr.stack.isHomeStack()) {
8229                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8230                            continue;
8231                        }
8232                    }
8233                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8234                        // Don't include auto remove tasks that are finished or finishing.
8235                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8236                                + tr);
8237                        continue;
8238                    }
8239                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8240                            && !tr.isAvailable) {
8241                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8242                        continue;
8243                    }
8244
8245                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8246                    if (!detailed) {
8247                        rti.baseIntent.replaceExtras((Bundle)null);
8248                    }
8249
8250                    res.add(rti);
8251                    maxNum--;
8252                }
8253            }
8254            return res;
8255        }
8256    }
8257
8258    private TaskRecord recentTaskForIdLocked(int id) {
8259        final int N = mRecentTasks.size();
8260            for (int i=0; i<N; i++) {
8261                TaskRecord tr = mRecentTasks.get(i);
8262                if (tr.taskId == id) {
8263                    return tr;
8264                }
8265            }
8266            return null;
8267    }
8268
8269    @Override
8270    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8271        synchronized (this) {
8272            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8273                    "getTaskThumbnail()");
8274            TaskRecord tr = recentTaskForIdLocked(id);
8275            if (tr != null) {
8276                return tr.getTaskThumbnailLocked();
8277            }
8278        }
8279        return null;
8280    }
8281
8282    @Override
8283    public int addAppTask(IBinder activityToken, Intent intent,
8284            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8285        final int callingUid = Binder.getCallingUid();
8286        final long callingIdent = Binder.clearCallingIdentity();
8287
8288        try {
8289            synchronized (this) {
8290                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8291                if (r == null) {
8292                    throw new IllegalArgumentException("Activity does not exist; token="
8293                            + activityToken);
8294                }
8295                ComponentName comp = intent.getComponent();
8296                if (comp == null) {
8297                    throw new IllegalArgumentException("Intent " + intent
8298                            + " must specify explicit component");
8299                }
8300                if (thumbnail.getWidth() != mThumbnailWidth
8301                        || thumbnail.getHeight() != mThumbnailHeight) {
8302                    throw new IllegalArgumentException("Bad thumbnail size: got "
8303                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8304                            + mThumbnailWidth + "x" + mThumbnailHeight);
8305                }
8306                if (intent.getSelector() != null) {
8307                    intent.setSelector(null);
8308                }
8309                if (intent.getSourceBounds() != null) {
8310                    intent.setSourceBounds(null);
8311                }
8312                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8313                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8314                        // The caller has added this as an auto-remove task...  that makes no
8315                        // sense, so turn off auto-remove.
8316                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8317                    }
8318                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8319                    // Must be a new task.
8320                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8321                }
8322                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8323                    mLastAddedTaskActivity = null;
8324                }
8325                ActivityInfo ainfo = mLastAddedTaskActivity;
8326                if (ainfo == null) {
8327                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8328                            comp, 0, UserHandle.getUserId(callingUid));
8329                    if (ainfo.applicationInfo.uid != callingUid) {
8330                        throw new SecurityException(
8331                                "Can't add task for another application: target uid="
8332                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8333                    }
8334                }
8335
8336                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8337                        intent, description);
8338
8339                int trimIdx = trimRecentsForTask(task, false);
8340                if (trimIdx >= 0) {
8341                    // If this would have caused a trim, then we'll abort because that
8342                    // means it would be added at the end of the list but then just removed.
8343                    return -1;
8344                }
8345
8346                final int N = mRecentTasks.size();
8347                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8348                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8349                    tr.removedFromRecents(mTaskPersister);
8350                }
8351
8352                task.inRecents = true;
8353                mRecentTasks.add(task);
8354                r.task.stack.addTask(task, false, false);
8355
8356                task.setLastThumbnail(thumbnail);
8357                task.freeLastThumbnail();
8358
8359                return task.taskId;
8360            }
8361        } finally {
8362            Binder.restoreCallingIdentity(callingIdent);
8363        }
8364    }
8365
8366    @Override
8367    public Point getAppTaskThumbnailSize() {
8368        synchronized (this) {
8369            return new Point(mThumbnailWidth,  mThumbnailHeight);
8370        }
8371    }
8372
8373    @Override
8374    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8375        synchronized (this) {
8376            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8377            if (r != null) {
8378                r.setTaskDescription(td);
8379                r.task.updateTaskDescription();
8380            }
8381        }
8382    }
8383
8384    @Override
8385    public Bitmap getTaskDescriptionIcon(String filename) {
8386        return mTaskPersister.getTaskDescriptionIcon(filename);
8387    }
8388
8389    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8390        mRecentTasks.remove(tr);
8391        tr.removedFromRecents(mTaskPersister);
8392        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8393        Intent baseIntent = new Intent(
8394                tr.intent != null ? tr.intent : tr.affinityIntent);
8395        ComponentName component = baseIntent.getComponent();
8396        if (component == null) {
8397            Slog.w(TAG, "Now component for base intent of task: " + tr);
8398            return;
8399        }
8400
8401        // Find any running services associated with this app.
8402        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8403
8404        if (killProcesses) {
8405            // Find any running processes associated with this app.
8406            final String pkg = component.getPackageName();
8407            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8408            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8409            for (int i=0; i<pmap.size(); i++) {
8410                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8411                for (int j=0; j<uids.size(); j++) {
8412                    ProcessRecord proc = uids.valueAt(j);
8413                    if (proc.userId != tr.userId) {
8414                        continue;
8415                    }
8416                    if (!proc.pkgList.containsKey(pkg)) {
8417                        continue;
8418                    }
8419                    procs.add(proc);
8420                }
8421            }
8422
8423            // Kill the running processes.
8424            for (int i=0; i<procs.size(); i++) {
8425                ProcessRecord pr = procs.get(i);
8426                if (pr == mHomeProcess) {
8427                    // Don't kill the home process along with tasks from the same package.
8428                    continue;
8429                }
8430                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8431                    pr.kill("remove task", true);
8432                } else {
8433                    pr.waitingToKill = "remove task";
8434                }
8435            }
8436        }
8437    }
8438
8439    /**
8440     * Removes the task with the specified task id.
8441     *
8442     * @param taskId Identifier of the task to be removed.
8443     * @param flags Additional operational flags.  May be 0 or
8444     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8445     * @return Returns true if the given task was found and removed.
8446     */
8447    private boolean removeTaskByIdLocked(int taskId, int flags) {
8448        TaskRecord tr = recentTaskForIdLocked(taskId);
8449        if (tr != null) {
8450            tr.removeTaskActivitiesLocked();
8451            cleanUpRemovedTaskLocked(tr, flags);
8452            if (tr.isPersistable) {
8453                notifyTaskPersisterLocked(null, true);
8454            }
8455            return true;
8456        }
8457        return false;
8458    }
8459
8460    @Override
8461    public boolean removeTask(int taskId, int flags) {
8462        synchronized (this) {
8463            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8464                    "removeTask()");
8465            long ident = Binder.clearCallingIdentity();
8466            try {
8467                return removeTaskByIdLocked(taskId, flags);
8468            } finally {
8469                Binder.restoreCallingIdentity(ident);
8470            }
8471        }
8472    }
8473
8474    /**
8475     * TODO: Add mController hook
8476     */
8477    @Override
8478    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8479        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8480                "moveTaskToFront()");
8481
8482        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8483        synchronized(this) {
8484            moveTaskToFrontLocked(taskId, flags, options);
8485        }
8486    }
8487
8488    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8489        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8490                Binder.getCallingUid(), -1, -1, "Task to front")) {
8491            ActivityOptions.abort(options);
8492            return;
8493        }
8494        final long origId = Binder.clearCallingIdentity();
8495        try {
8496            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8497            if (task == null) {
8498                return;
8499            }
8500            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8501                mStackSupervisor.showLockTaskToast();
8502                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8503                return;
8504            }
8505            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8506            if (prev != null && prev.isRecentsActivity()) {
8507                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8508            }
8509            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8510        } finally {
8511            Binder.restoreCallingIdentity(origId);
8512        }
8513        ActivityOptions.abort(options);
8514    }
8515
8516    @Override
8517    public void moveTaskToBack(int taskId) {
8518        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8519                "moveTaskToBack()");
8520
8521        synchronized(this) {
8522            TaskRecord tr = recentTaskForIdLocked(taskId);
8523            if (tr != null) {
8524                if (tr == mStackSupervisor.mLockTaskModeTask) {
8525                    mStackSupervisor.showLockTaskToast();
8526                    return;
8527                }
8528                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8529                ActivityStack stack = tr.stack;
8530                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8531                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8532                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8533                        return;
8534                    }
8535                }
8536                final long origId = Binder.clearCallingIdentity();
8537                try {
8538                    stack.moveTaskToBackLocked(taskId, null);
8539                } finally {
8540                    Binder.restoreCallingIdentity(origId);
8541                }
8542            }
8543        }
8544    }
8545
8546    /**
8547     * Moves an activity, and all of the other activities within the same task, to the bottom
8548     * of the history stack.  The activity's order within the task is unchanged.
8549     *
8550     * @param token A reference to the activity we wish to move
8551     * @param nonRoot If false then this only works if the activity is the root
8552     *                of a task; if true it will work for any activity in a task.
8553     * @return Returns true if the move completed, false if not.
8554     */
8555    @Override
8556    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8557        enforceNotIsolatedCaller("moveActivityTaskToBack");
8558        synchronized(this) {
8559            final long origId = Binder.clearCallingIdentity();
8560            try {
8561                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8562                if (taskId >= 0) {
8563                    if ((mStackSupervisor.mLockTaskModeTask != null)
8564                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8565                        mStackSupervisor.showLockTaskToast();
8566                        return false;
8567                    }
8568                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8569                }
8570            } finally {
8571                Binder.restoreCallingIdentity(origId);
8572            }
8573        }
8574        return false;
8575    }
8576
8577    @Override
8578    public void moveTaskBackwards(int task) {
8579        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8580                "moveTaskBackwards()");
8581
8582        synchronized(this) {
8583            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8584                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8585                return;
8586            }
8587            final long origId = Binder.clearCallingIdentity();
8588            moveTaskBackwardsLocked(task);
8589            Binder.restoreCallingIdentity(origId);
8590        }
8591    }
8592
8593    private final void moveTaskBackwardsLocked(int task) {
8594        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8595    }
8596
8597    @Override
8598    public IBinder getHomeActivityToken() throws RemoteException {
8599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8600                "getHomeActivityToken()");
8601        synchronized (this) {
8602            return mStackSupervisor.getHomeActivityToken();
8603        }
8604    }
8605
8606    @Override
8607    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8608            IActivityContainerCallback callback) throws RemoteException {
8609        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8610                "createActivityContainer()");
8611        synchronized (this) {
8612            if (parentActivityToken == null) {
8613                throw new IllegalArgumentException("parent token must not be null");
8614            }
8615            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8616            if (r == null) {
8617                return null;
8618            }
8619            if (callback == null) {
8620                throw new IllegalArgumentException("callback must not be null");
8621            }
8622            return mStackSupervisor.createActivityContainer(r, callback);
8623        }
8624    }
8625
8626    @Override
8627    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8628        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8629                "deleteActivityContainer()");
8630        synchronized (this) {
8631            mStackSupervisor.deleteActivityContainer(container);
8632        }
8633    }
8634
8635    @Override
8636    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8637            throws RemoteException {
8638        synchronized (this) {
8639            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8640            if (stack != null) {
8641                return stack.mActivityContainer;
8642            }
8643            return null;
8644        }
8645    }
8646
8647    @Override
8648    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8649        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8650                "moveTaskToStack()");
8651        if (stackId == HOME_STACK_ID) {
8652            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8653                    new RuntimeException("here").fillInStackTrace());
8654        }
8655        synchronized (this) {
8656            long ident = Binder.clearCallingIdentity();
8657            try {
8658                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8659                        + stackId + " toTop=" + toTop);
8660                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8661            } finally {
8662                Binder.restoreCallingIdentity(ident);
8663            }
8664        }
8665    }
8666
8667    @Override
8668    public void resizeStack(int stackBoxId, Rect bounds) {
8669        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8670                "resizeStackBox()");
8671        long ident = Binder.clearCallingIdentity();
8672        try {
8673            mWindowManager.resizeStack(stackBoxId, bounds);
8674        } finally {
8675            Binder.restoreCallingIdentity(ident);
8676        }
8677    }
8678
8679    @Override
8680    public List<StackInfo> getAllStackInfos() {
8681        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8682                "getAllStackInfos()");
8683        long ident = Binder.clearCallingIdentity();
8684        try {
8685            synchronized (this) {
8686                return mStackSupervisor.getAllStackInfosLocked();
8687            }
8688        } finally {
8689            Binder.restoreCallingIdentity(ident);
8690        }
8691    }
8692
8693    @Override
8694    public StackInfo getStackInfo(int stackId) {
8695        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8696                "getStackInfo()");
8697        long ident = Binder.clearCallingIdentity();
8698        try {
8699            synchronized (this) {
8700                return mStackSupervisor.getStackInfoLocked(stackId);
8701            }
8702        } finally {
8703            Binder.restoreCallingIdentity(ident);
8704        }
8705    }
8706
8707    @Override
8708    public boolean isInHomeStack(int taskId) {
8709        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8710                "getStackInfo()");
8711        long ident = Binder.clearCallingIdentity();
8712        try {
8713            synchronized (this) {
8714                TaskRecord tr = recentTaskForIdLocked(taskId);
8715                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8716            }
8717        } finally {
8718            Binder.restoreCallingIdentity(ident);
8719        }
8720    }
8721
8722    @Override
8723    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8724        synchronized(this) {
8725            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8726        }
8727    }
8728
8729    private boolean isLockTaskAuthorized(String pkg) {
8730        final DevicePolicyManager dpm = (DevicePolicyManager)
8731                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8732        try {
8733            int uid = mContext.getPackageManager().getPackageUid(pkg,
8734                    Binder.getCallingUserHandle().getIdentifier());
8735            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8736        } catch (NameNotFoundException e) {
8737            return false;
8738        }
8739    }
8740
8741    void startLockTaskMode(TaskRecord task) {
8742        final String pkg;
8743        synchronized (this) {
8744            pkg = task.intent.getComponent().getPackageName();
8745        }
8746        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8747        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8748            final TaskRecord taskRecord = task;
8749            mHandler.post(new Runnable() {
8750                @Override
8751                public void run() {
8752                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8753                }
8754            });
8755            return;
8756        }
8757        long ident = Binder.clearCallingIdentity();
8758        try {
8759            synchronized (this) {
8760                // Since we lost lock on task, make sure it is still there.
8761                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8762                if (task != null) {
8763                    if (!isSystemInitiated
8764                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8765                        throw new IllegalArgumentException("Invalid task, not in foreground");
8766                    }
8767                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8768                }
8769            }
8770        } finally {
8771            Binder.restoreCallingIdentity(ident);
8772        }
8773    }
8774
8775    @Override
8776    public void startLockTaskMode(int taskId) {
8777        final TaskRecord task;
8778        long ident = Binder.clearCallingIdentity();
8779        try {
8780            synchronized (this) {
8781                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8782            }
8783        } finally {
8784            Binder.restoreCallingIdentity(ident);
8785        }
8786        if (task != null) {
8787            startLockTaskMode(task);
8788        }
8789    }
8790
8791    @Override
8792    public void startLockTaskMode(IBinder token) {
8793        final TaskRecord task;
8794        long ident = Binder.clearCallingIdentity();
8795        try {
8796            synchronized (this) {
8797                final ActivityRecord r = ActivityRecord.forToken(token);
8798                if (r == null) {
8799                    return;
8800                }
8801                task = r.task;
8802            }
8803        } finally {
8804            Binder.restoreCallingIdentity(ident);
8805        }
8806        if (task != null) {
8807            startLockTaskMode(task);
8808        }
8809    }
8810
8811    @Override
8812    public void startLockTaskModeOnCurrent() throws RemoteException {
8813        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8814                "startLockTaskModeOnCurrent");
8815        ActivityRecord r = null;
8816        synchronized (this) {
8817            r = mStackSupervisor.topRunningActivityLocked();
8818        }
8819        startLockTaskMode(r.task);
8820    }
8821
8822    @Override
8823    public void stopLockTaskMode() {
8824        // Verify that the user matches the package of the intent for the TaskRecord
8825        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8826        // and stopLockTaskMode.
8827        final int callingUid = Binder.getCallingUid();
8828        if (callingUid != Process.SYSTEM_UID) {
8829            try {
8830                String pkg =
8831                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8832                int uid = mContext.getPackageManager().getPackageUid(pkg,
8833                        Binder.getCallingUserHandle().getIdentifier());
8834                if (uid != callingUid) {
8835                    throw new SecurityException("Invalid uid, expected " + uid);
8836                }
8837            } catch (NameNotFoundException e) {
8838                Log.d(TAG, "stopLockTaskMode " + e);
8839                return;
8840            }
8841        }
8842        long ident = Binder.clearCallingIdentity();
8843        try {
8844            Log.d(TAG, "stopLockTaskMode");
8845            // Stop lock task
8846            synchronized (this) {
8847                mStackSupervisor.setLockTaskModeLocked(null, false);
8848            }
8849        } finally {
8850            Binder.restoreCallingIdentity(ident);
8851        }
8852    }
8853
8854    @Override
8855    public void stopLockTaskModeOnCurrent() throws RemoteException {
8856        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8857                "stopLockTaskModeOnCurrent");
8858        long ident = Binder.clearCallingIdentity();
8859        try {
8860            stopLockTaskMode();
8861        } finally {
8862            Binder.restoreCallingIdentity(ident);
8863        }
8864    }
8865
8866    @Override
8867    public boolean isInLockTaskMode() {
8868        synchronized (this) {
8869            return mStackSupervisor.isInLockTaskMode();
8870        }
8871    }
8872
8873    // =========================================================
8874    // CONTENT PROVIDERS
8875    // =========================================================
8876
8877    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8878        List<ProviderInfo> providers = null;
8879        try {
8880            providers = AppGlobals.getPackageManager().
8881                queryContentProviders(app.processName, app.uid,
8882                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8883        } catch (RemoteException ex) {
8884        }
8885        if (DEBUG_MU)
8886            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8887        int userId = app.userId;
8888        if (providers != null) {
8889            int N = providers.size();
8890            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8891            for (int i=0; i<N; i++) {
8892                ProviderInfo cpi =
8893                    (ProviderInfo)providers.get(i);
8894                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8895                        cpi.name, cpi.flags);
8896                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8897                    // This is a singleton provider, but a user besides the
8898                    // default user is asking to initialize a process it runs
8899                    // in...  well, no, it doesn't actually run in this process,
8900                    // it runs in the process of the default user.  Get rid of it.
8901                    providers.remove(i);
8902                    N--;
8903                    i--;
8904                    continue;
8905                }
8906
8907                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8908                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8909                if (cpr == null) {
8910                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8911                    mProviderMap.putProviderByClass(comp, cpr);
8912                }
8913                if (DEBUG_MU)
8914                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8915                app.pubProviders.put(cpi.name, cpr);
8916                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8917                    // Don't add this if it is a platform component that is marked
8918                    // to run in multiple processes, because this is actually
8919                    // part of the framework so doesn't make sense to track as a
8920                    // separate apk in the process.
8921                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8922                            mProcessStats);
8923                }
8924                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8925            }
8926        }
8927        return providers;
8928    }
8929
8930    /**
8931     * Check if {@link ProcessRecord} has a possible chance at accessing the
8932     * given {@link ProviderInfo}. Final permission checking is always done
8933     * in {@link ContentProvider}.
8934     */
8935    private final String checkContentProviderPermissionLocked(
8936            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8937        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8938        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8939        boolean checkedGrants = false;
8940        if (checkUser) {
8941            // Looking for cross-user grants before enforcing the typical cross-users permissions
8942            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8943            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8944                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8945                    return null;
8946                }
8947                checkedGrants = true;
8948            }
8949            userId = handleIncomingUser(callingPid, callingUid, userId,
8950                    false, ALLOW_NON_FULL,
8951                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8952            if (userId != tmpTargetUserId) {
8953                // When we actually went to determine the final targer user ID, this ended
8954                // up different than our initial check for the authority.  This is because
8955                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8956                // SELF.  So we need to re-check the grants again.
8957                checkedGrants = false;
8958            }
8959        }
8960        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8961                cpi.applicationInfo.uid, cpi.exported)
8962                == PackageManager.PERMISSION_GRANTED) {
8963            return null;
8964        }
8965        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8966                cpi.applicationInfo.uid, cpi.exported)
8967                == PackageManager.PERMISSION_GRANTED) {
8968            return null;
8969        }
8970
8971        PathPermission[] pps = cpi.pathPermissions;
8972        if (pps != null) {
8973            int i = pps.length;
8974            while (i > 0) {
8975                i--;
8976                PathPermission pp = pps[i];
8977                String pprperm = pp.getReadPermission();
8978                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8979                        cpi.applicationInfo.uid, cpi.exported)
8980                        == PackageManager.PERMISSION_GRANTED) {
8981                    return null;
8982                }
8983                String ppwperm = pp.getWritePermission();
8984                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8985                        cpi.applicationInfo.uid, cpi.exported)
8986                        == PackageManager.PERMISSION_GRANTED) {
8987                    return null;
8988                }
8989            }
8990        }
8991        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8992            return null;
8993        }
8994
8995        String msg;
8996        if (!cpi.exported) {
8997            msg = "Permission Denial: opening provider " + cpi.name
8998                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8999                    + ", uid=" + callingUid + ") that is not exported from uid "
9000                    + cpi.applicationInfo.uid;
9001        } else {
9002            msg = "Permission Denial: opening provider " + cpi.name
9003                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9004                    + ", uid=" + callingUid + ") requires "
9005                    + cpi.readPermission + " or " + cpi.writePermission;
9006        }
9007        Slog.w(TAG, msg);
9008        return msg;
9009    }
9010
9011    /**
9012     * Returns if the ContentProvider has granted a uri to callingUid
9013     */
9014    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9015        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9016        if (perms != null) {
9017            for (int i=perms.size()-1; i>=0; i--) {
9018                GrantUri grantUri = perms.keyAt(i);
9019                if (grantUri.sourceUserId == userId || !checkUser) {
9020                    if (matchesProvider(grantUri.uri, cpi)) {
9021                        return true;
9022                    }
9023                }
9024            }
9025        }
9026        return false;
9027    }
9028
9029    /**
9030     * Returns true if the uri authority is one of the authorities specified in the provider.
9031     */
9032    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9033        String uriAuth = uri.getAuthority();
9034        String cpiAuth = cpi.authority;
9035        if (cpiAuth.indexOf(';') == -1) {
9036            return cpiAuth.equals(uriAuth);
9037        }
9038        String[] cpiAuths = cpiAuth.split(";");
9039        int length = cpiAuths.length;
9040        for (int i = 0; i < length; i++) {
9041            if (cpiAuths[i].equals(uriAuth)) return true;
9042        }
9043        return false;
9044    }
9045
9046    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9047            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9048        if (r != null) {
9049            for (int i=0; i<r.conProviders.size(); i++) {
9050                ContentProviderConnection conn = r.conProviders.get(i);
9051                if (conn.provider == cpr) {
9052                    if (DEBUG_PROVIDER) Slog.v(TAG,
9053                            "Adding provider requested by "
9054                            + r.processName + " from process "
9055                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9056                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9057                    if (stable) {
9058                        conn.stableCount++;
9059                        conn.numStableIncs++;
9060                    } else {
9061                        conn.unstableCount++;
9062                        conn.numUnstableIncs++;
9063                    }
9064                    return conn;
9065                }
9066            }
9067            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9068            if (stable) {
9069                conn.stableCount = 1;
9070                conn.numStableIncs = 1;
9071            } else {
9072                conn.unstableCount = 1;
9073                conn.numUnstableIncs = 1;
9074            }
9075            cpr.connections.add(conn);
9076            r.conProviders.add(conn);
9077            return conn;
9078        }
9079        cpr.addExternalProcessHandleLocked(externalProcessToken);
9080        return null;
9081    }
9082
9083    boolean decProviderCountLocked(ContentProviderConnection conn,
9084            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9085        if (conn != null) {
9086            cpr = conn.provider;
9087            if (DEBUG_PROVIDER) Slog.v(TAG,
9088                    "Removing provider requested by "
9089                    + conn.client.processName + " from process "
9090                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9091                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9092            if (stable) {
9093                conn.stableCount--;
9094            } else {
9095                conn.unstableCount--;
9096            }
9097            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9098                cpr.connections.remove(conn);
9099                conn.client.conProviders.remove(conn);
9100                return true;
9101            }
9102            return false;
9103        }
9104        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9105        return false;
9106    }
9107
9108    private void checkTime(long startTime, String where) {
9109        long now = SystemClock.elapsedRealtime();
9110        if ((now-startTime) > 1000) {
9111            // If we are taking more than a second, log about it.
9112            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9113        }
9114    }
9115
9116    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9117            String name, IBinder token, boolean stable, int userId) {
9118        ContentProviderRecord cpr;
9119        ContentProviderConnection conn = null;
9120        ProviderInfo cpi = null;
9121
9122        synchronized(this) {
9123            long startTime = SystemClock.elapsedRealtime();
9124
9125            ProcessRecord r = null;
9126            if (caller != null) {
9127                r = getRecordForAppLocked(caller);
9128                if (r == null) {
9129                    throw new SecurityException(
9130                            "Unable to find app for caller " + caller
9131                          + " (pid=" + Binder.getCallingPid()
9132                          + ") when getting content provider " + name);
9133                }
9134            }
9135
9136            boolean checkCrossUser = true;
9137
9138            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9139
9140            // First check if this content provider has been published...
9141            cpr = mProviderMap.getProviderByName(name, userId);
9142            // If that didn't work, check if it exists for user 0 and then
9143            // verify that it's a singleton provider before using it.
9144            if (cpr == null && userId != UserHandle.USER_OWNER) {
9145                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9146                if (cpr != null) {
9147                    cpi = cpr.info;
9148                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9149                            cpi.name, cpi.flags)
9150                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9151                        userId = UserHandle.USER_OWNER;
9152                        checkCrossUser = false;
9153                    } else {
9154                        cpr = null;
9155                        cpi = null;
9156                    }
9157                }
9158            }
9159
9160            boolean providerRunning = cpr != null;
9161            if (providerRunning) {
9162                cpi = cpr.info;
9163                String msg;
9164                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9165                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9166                        != null) {
9167                    throw new SecurityException(msg);
9168                }
9169                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9170
9171                if (r != null && cpr.canRunHere(r)) {
9172                    // This provider has been published or is in the process
9173                    // of being published...  but it is also allowed to run
9174                    // in the caller's process, so don't make a connection
9175                    // and just let the caller instantiate its own instance.
9176                    ContentProviderHolder holder = cpr.newHolder(null);
9177                    // don't give caller the provider object, it needs
9178                    // to make its own.
9179                    holder.provider = null;
9180                    return holder;
9181                }
9182
9183                final long origId = Binder.clearCallingIdentity();
9184
9185                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9186
9187                // In this case the provider instance already exists, so we can
9188                // return it right away.
9189                conn = incProviderCountLocked(r, cpr, token, stable);
9190                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9191                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9192                        // If this is a perceptible app accessing the provider,
9193                        // make sure to count it as being accessed and thus
9194                        // back up on the LRU list.  This is good because
9195                        // content providers are often expensive to start.
9196                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9197                        updateLruProcessLocked(cpr.proc, false, null);
9198                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9199                    }
9200                }
9201
9202                if (cpr.proc != null) {
9203                    if (false) {
9204                        if (cpr.name.flattenToShortString().equals(
9205                                "com.android.providers.calendar/.CalendarProvider2")) {
9206                            Slog.v(TAG, "****************** KILLING "
9207                                + cpr.name.flattenToShortString());
9208                            Process.killProcess(cpr.proc.pid);
9209                        }
9210                    }
9211                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9212                    boolean success = updateOomAdjLocked(cpr.proc);
9213                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9214                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9215                    // NOTE: there is still a race here where a signal could be
9216                    // pending on the process even though we managed to update its
9217                    // adj level.  Not sure what to do about this, but at least
9218                    // the race is now smaller.
9219                    if (!success) {
9220                        // Uh oh...  it looks like the provider's process
9221                        // has been killed on us.  We need to wait for a new
9222                        // process to be started, and make sure its death
9223                        // doesn't kill our process.
9224                        Slog.i(TAG,
9225                                "Existing provider " + cpr.name.flattenToShortString()
9226                                + " is crashing; detaching " + r);
9227                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9228                        checkTime(startTime, "getContentProviderImpl: before appDied");
9229                        appDiedLocked(cpr.proc);
9230                        checkTime(startTime, "getContentProviderImpl: after appDied");
9231                        if (!lastRef) {
9232                            // This wasn't the last ref our process had on
9233                            // the provider...  we have now been killed, bail.
9234                            return null;
9235                        }
9236                        providerRunning = false;
9237                        conn = null;
9238                    }
9239                }
9240
9241                Binder.restoreCallingIdentity(origId);
9242            }
9243
9244            boolean singleton;
9245            if (!providerRunning) {
9246                try {
9247                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9248                    cpi = AppGlobals.getPackageManager().
9249                        resolveContentProvider(name,
9250                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9251                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9252                } catch (RemoteException ex) {
9253                }
9254                if (cpi == null) {
9255                    return null;
9256                }
9257                // If the provider is a singleton AND
9258                // (it's a call within the same user || the provider is a
9259                // privileged app)
9260                // Then allow connecting to the singleton provider
9261                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9262                        cpi.name, cpi.flags)
9263                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9264                if (singleton) {
9265                    userId = UserHandle.USER_OWNER;
9266                }
9267                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9268                checkTime(startTime, "getContentProviderImpl: got app info for user");
9269
9270                String msg;
9271                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9272                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9273                        != null) {
9274                    throw new SecurityException(msg);
9275                }
9276                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9277
9278                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9279                        && !cpi.processName.equals("system")) {
9280                    // If this content provider does not run in the system
9281                    // process, and the system is not yet ready to run other
9282                    // processes, then fail fast instead of hanging.
9283                    throw new IllegalArgumentException(
9284                            "Attempt to launch content provider before system ready");
9285                }
9286
9287                // Make sure that the user who owns this provider is started.  If not,
9288                // we don't want to allow it to run.
9289                if (mStartedUsers.get(userId) == null) {
9290                    Slog.w(TAG, "Unable to launch app "
9291                            + cpi.applicationInfo.packageName + "/"
9292                            + cpi.applicationInfo.uid + " for provider "
9293                            + name + ": user " + userId + " is stopped");
9294                    return null;
9295                }
9296
9297                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9298                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9299                cpr = mProviderMap.getProviderByClass(comp, userId);
9300                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9301                final boolean firstClass = cpr == null;
9302                if (firstClass) {
9303                    try {
9304                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9305                        ApplicationInfo ai =
9306                            AppGlobals.getPackageManager().
9307                                getApplicationInfo(
9308                                        cpi.applicationInfo.packageName,
9309                                        STOCK_PM_FLAGS, userId);
9310                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9311                        if (ai == null) {
9312                            Slog.w(TAG, "No package info for content provider "
9313                                    + cpi.name);
9314                            return null;
9315                        }
9316                        ai = getAppInfoForUser(ai, userId);
9317                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9318                    } catch (RemoteException ex) {
9319                        // pm is in same process, this will never happen.
9320                    }
9321                }
9322
9323                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9324
9325                if (r != null && cpr.canRunHere(r)) {
9326                    // If this is a multiprocess provider, then just return its
9327                    // info and allow the caller to instantiate it.  Only do
9328                    // this if the provider is the same user as the caller's
9329                    // process, or can run as root (so can be in any process).
9330                    return cpr.newHolder(null);
9331                }
9332
9333                if (DEBUG_PROVIDER) {
9334                    RuntimeException e = new RuntimeException("here");
9335                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9336                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9337                }
9338
9339                // This is single process, and our app is now connecting to it.
9340                // See if we are already in the process of launching this
9341                // provider.
9342                final int N = mLaunchingProviders.size();
9343                int i;
9344                for (i=0; i<N; i++) {
9345                    if (mLaunchingProviders.get(i) == cpr) {
9346                        break;
9347                    }
9348                }
9349
9350                // If the provider is not already being launched, then get it
9351                // started.
9352                if (i >= N) {
9353                    final long origId = Binder.clearCallingIdentity();
9354
9355                    try {
9356                        // Content provider is now in use, its package can't be stopped.
9357                        try {
9358                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9359                            AppGlobals.getPackageManager().setPackageStoppedState(
9360                                    cpr.appInfo.packageName, false, userId);
9361                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9362                        } catch (RemoteException e) {
9363                        } catch (IllegalArgumentException e) {
9364                            Slog.w(TAG, "Failed trying to unstop package "
9365                                    + cpr.appInfo.packageName + ": " + e);
9366                        }
9367
9368                        // Use existing process if already started
9369                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9370                        ProcessRecord proc = getProcessRecordLocked(
9371                                cpi.processName, cpr.appInfo.uid, false);
9372                        if (proc != null && proc.thread != null) {
9373                            if (DEBUG_PROVIDER) {
9374                                Slog.d(TAG, "Installing in existing process " + proc);
9375                            }
9376                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9377                            proc.pubProviders.put(cpi.name, cpr);
9378                            try {
9379                                proc.thread.scheduleInstallProvider(cpi);
9380                            } catch (RemoteException e) {
9381                            }
9382                        } else {
9383                            checkTime(startTime, "getContentProviderImpl: before start process");
9384                            proc = startProcessLocked(cpi.processName,
9385                                    cpr.appInfo, false, 0, "content provider",
9386                                    new ComponentName(cpi.applicationInfo.packageName,
9387                                            cpi.name), false, false, false);
9388                            checkTime(startTime, "getContentProviderImpl: after start process");
9389                            if (proc == null) {
9390                                Slog.w(TAG, "Unable to launch app "
9391                                        + cpi.applicationInfo.packageName + "/"
9392                                        + cpi.applicationInfo.uid + " for provider "
9393                                        + name + ": process is bad");
9394                                return null;
9395                            }
9396                        }
9397                        cpr.launchingApp = proc;
9398                        mLaunchingProviders.add(cpr);
9399                    } finally {
9400                        Binder.restoreCallingIdentity(origId);
9401                    }
9402                }
9403
9404                checkTime(startTime, "getContentProviderImpl: updating data structures");
9405
9406                // Make sure the provider is published (the same provider class
9407                // may be published under multiple names).
9408                if (firstClass) {
9409                    mProviderMap.putProviderByClass(comp, cpr);
9410                }
9411
9412                mProviderMap.putProviderByName(name, cpr);
9413                conn = incProviderCountLocked(r, cpr, token, stable);
9414                if (conn != null) {
9415                    conn.waiting = true;
9416                }
9417            }
9418            checkTime(startTime, "getContentProviderImpl: done!");
9419        }
9420
9421        // Wait for the provider to be published...
9422        synchronized (cpr) {
9423            while (cpr.provider == null) {
9424                if (cpr.launchingApp == null) {
9425                    Slog.w(TAG, "Unable to launch app "
9426                            + cpi.applicationInfo.packageName + "/"
9427                            + cpi.applicationInfo.uid + " for provider "
9428                            + name + ": launching app became null");
9429                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9430                            UserHandle.getUserId(cpi.applicationInfo.uid),
9431                            cpi.applicationInfo.packageName,
9432                            cpi.applicationInfo.uid, name);
9433                    return null;
9434                }
9435                try {
9436                    if (DEBUG_MU) {
9437                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9438                                + cpr.launchingApp);
9439                    }
9440                    if (conn != null) {
9441                        conn.waiting = true;
9442                    }
9443                    cpr.wait();
9444                } catch (InterruptedException ex) {
9445                } finally {
9446                    if (conn != null) {
9447                        conn.waiting = false;
9448                    }
9449                }
9450            }
9451        }
9452        return cpr != null ? cpr.newHolder(conn) : null;
9453    }
9454
9455    @Override
9456    public final ContentProviderHolder getContentProvider(
9457            IApplicationThread caller, String name, int userId, boolean stable) {
9458        enforceNotIsolatedCaller("getContentProvider");
9459        if (caller == null) {
9460            String msg = "null IApplicationThread when getting content provider "
9461                    + name;
9462            Slog.w(TAG, msg);
9463            throw new SecurityException(msg);
9464        }
9465        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9466        // with cross-user grant.
9467        return getContentProviderImpl(caller, name, null, stable, userId);
9468    }
9469
9470    public ContentProviderHolder getContentProviderExternal(
9471            String name, int userId, IBinder token) {
9472        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9473            "Do not have permission in call getContentProviderExternal()");
9474        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9475                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9476        return getContentProviderExternalUnchecked(name, token, userId);
9477    }
9478
9479    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9480            IBinder token, int userId) {
9481        return getContentProviderImpl(null, name, token, true, userId);
9482    }
9483
9484    /**
9485     * Drop a content provider from a ProcessRecord's bookkeeping
9486     */
9487    public void removeContentProvider(IBinder connection, boolean stable) {
9488        enforceNotIsolatedCaller("removeContentProvider");
9489        long ident = Binder.clearCallingIdentity();
9490        try {
9491            synchronized (this) {
9492                ContentProviderConnection conn;
9493                try {
9494                    conn = (ContentProviderConnection)connection;
9495                } catch (ClassCastException e) {
9496                    String msg ="removeContentProvider: " + connection
9497                            + " not a ContentProviderConnection";
9498                    Slog.w(TAG, msg);
9499                    throw new IllegalArgumentException(msg);
9500                }
9501                if (conn == null) {
9502                    throw new NullPointerException("connection is null");
9503                }
9504                if (decProviderCountLocked(conn, null, null, stable)) {
9505                    updateOomAdjLocked();
9506                }
9507            }
9508        } finally {
9509            Binder.restoreCallingIdentity(ident);
9510        }
9511    }
9512
9513    public void removeContentProviderExternal(String name, IBinder token) {
9514        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9515            "Do not have permission in call removeContentProviderExternal()");
9516        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9517    }
9518
9519    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9520        synchronized (this) {
9521            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9522            if(cpr == null) {
9523                //remove from mProvidersByClass
9524                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9525                return;
9526            }
9527
9528            //update content provider record entry info
9529            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9530            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9531            if (localCpr.hasExternalProcessHandles()) {
9532                if (localCpr.removeExternalProcessHandleLocked(token)) {
9533                    updateOomAdjLocked();
9534                } else {
9535                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9536                            + " with no external reference for token: "
9537                            + token + ".");
9538                }
9539            } else {
9540                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9541                        + " with no external references.");
9542            }
9543        }
9544    }
9545
9546    public final void publishContentProviders(IApplicationThread caller,
9547            List<ContentProviderHolder> providers) {
9548        if (providers == null) {
9549            return;
9550        }
9551
9552        enforceNotIsolatedCaller("publishContentProviders");
9553        synchronized (this) {
9554            final ProcessRecord r = getRecordForAppLocked(caller);
9555            if (DEBUG_MU)
9556                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9557            if (r == null) {
9558                throw new SecurityException(
9559                        "Unable to find app for caller " + caller
9560                      + " (pid=" + Binder.getCallingPid()
9561                      + ") when publishing content providers");
9562            }
9563
9564            final long origId = Binder.clearCallingIdentity();
9565
9566            final int N = providers.size();
9567            for (int i=0; i<N; i++) {
9568                ContentProviderHolder src = providers.get(i);
9569                if (src == null || src.info == null || src.provider == null) {
9570                    continue;
9571                }
9572                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9573                if (DEBUG_MU)
9574                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9575                if (dst != null) {
9576                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9577                    mProviderMap.putProviderByClass(comp, dst);
9578                    String names[] = dst.info.authority.split(";");
9579                    for (int j = 0; j < names.length; j++) {
9580                        mProviderMap.putProviderByName(names[j], dst);
9581                    }
9582
9583                    int NL = mLaunchingProviders.size();
9584                    int j;
9585                    for (j=0; j<NL; j++) {
9586                        if (mLaunchingProviders.get(j) == dst) {
9587                            mLaunchingProviders.remove(j);
9588                            j--;
9589                            NL--;
9590                        }
9591                    }
9592                    synchronized (dst) {
9593                        dst.provider = src.provider;
9594                        dst.proc = r;
9595                        dst.notifyAll();
9596                    }
9597                    updateOomAdjLocked(r);
9598                }
9599            }
9600
9601            Binder.restoreCallingIdentity(origId);
9602        }
9603    }
9604
9605    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9606        ContentProviderConnection conn;
9607        try {
9608            conn = (ContentProviderConnection)connection;
9609        } catch (ClassCastException e) {
9610            String msg ="refContentProvider: " + connection
9611                    + " not a ContentProviderConnection";
9612            Slog.w(TAG, msg);
9613            throw new IllegalArgumentException(msg);
9614        }
9615        if (conn == null) {
9616            throw new NullPointerException("connection is null");
9617        }
9618
9619        synchronized (this) {
9620            if (stable > 0) {
9621                conn.numStableIncs += stable;
9622            }
9623            stable = conn.stableCount + stable;
9624            if (stable < 0) {
9625                throw new IllegalStateException("stableCount < 0: " + stable);
9626            }
9627
9628            if (unstable > 0) {
9629                conn.numUnstableIncs += unstable;
9630            }
9631            unstable = conn.unstableCount + unstable;
9632            if (unstable < 0) {
9633                throw new IllegalStateException("unstableCount < 0: " + unstable);
9634            }
9635
9636            if ((stable+unstable) <= 0) {
9637                throw new IllegalStateException("ref counts can't go to zero here: stable="
9638                        + stable + " unstable=" + unstable);
9639            }
9640            conn.stableCount = stable;
9641            conn.unstableCount = unstable;
9642            return !conn.dead;
9643        }
9644    }
9645
9646    public void unstableProviderDied(IBinder connection) {
9647        ContentProviderConnection conn;
9648        try {
9649            conn = (ContentProviderConnection)connection;
9650        } catch (ClassCastException e) {
9651            String msg ="refContentProvider: " + connection
9652                    + " not a ContentProviderConnection";
9653            Slog.w(TAG, msg);
9654            throw new IllegalArgumentException(msg);
9655        }
9656        if (conn == null) {
9657            throw new NullPointerException("connection is null");
9658        }
9659
9660        // Safely retrieve the content provider associated with the connection.
9661        IContentProvider provider;
9662        synchronized (this) {
9663            provider = conn.provider.provider;
9664        }
9665
9666        if (provider == null) {
9667            // Um, yeah, we're way ahead of you.
9668            return;
9669        }
9670
9671        // Make sure the caller is being honest with us.
9672        if (provider.asBinder().pingBinder()) {
9673            // Er, no, still looks good to us.
9674            synchronized (this) {
9675                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9676                        + " says " + conn + " died, but we don't agree");
9677                return;
9678            }
9679        }
9680
9681        // Well look at that!  It's dead!
9682        synchronized (this) {
9683            if (conn.provider.provider != provider) {
9684                // But something changed...  good enough.
9685                return;
9686            }
9687
9688            ProcessRecord proc = conn.provider.proc;
9689            if (proc == null || proc.thread == null) {
9690                // Seems like the process is already cleaned up.
9691                return;
9692            }
9693
9694            // As far as we're concerned, this is just like receiving a
9695            // death notification...  just a bit prematurely.
9696            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9697                    + ") early provider death");
9698            final long ident = Binder.clearCallingIdentity();
9699            try {
9700                appDiedLocked(proc);
9701            } finally {
9702                Binder.restoreCallingIdentity(ident);
9703            }
9704        }
9705    }
9706
9707    @Override
9708    public void appNotRespondingViaProvider(IBinder connection) {
9709        enforceCallingPermission(
9710                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9711
9712        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9713        if (conn == null) {
9714            Slog.w(TAG, "ContentProviderConnection is null");
9715            return;
9716        }
9717
9718        final ProcessRecord host = conn.provider.proc;
9719        if (host == null) {
9720            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9721            return;
9722        }
9723
9724        final long token = Binder.clearCallingIdentity();
9725        try {
9726            appNotResponding(host, null, null, false, "ContentProvider not responding");
9727        } finally {
9728            Binder.restoreCallingIdentity(token);
9729        }
9730    }
9731
9732    public final void installSystemProviders() {
9733        List<ProviderInfo> providers;
9734        synchronized (this) {
9735            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9736            providers = generateApplicationProvidersLocked(app);
9737            if (providers != null) {
9738                for (int i=providers.size()-1; i>=0; i--) {
9739                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9740                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9741                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9742                                + ": not system .apk");
9743                        providers.remove(i);
9744                    }
9745                }
9746            }
9747        }
9748        if (providers != null) {
9749            mSystemThread.installSystemProviders(providers);
9750        }
9751
9752        mCoreSettingsObserver = new CoreSettingsObserver(this);
9753
9754        //mUsageStatsService.monitorPackages();
9755    }
9756
9757    /**
9758     * Allows apps to retrieve the MIME type of a URI.
9759     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9760     * users, then it does not need permission to access the ContentProvider.
9761     * Either, it needs cross-user uri grants.
9762     *
9763     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9764     *
9765     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9766     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9767     */
9768    public String getProviderMimeType(Uri uri, int userId) {
9769        enforceNotIsolatedCaller("getProviderMimeType");
9770        final String name = uri.getAuthority();
9771        int callingUid = Binder.getCallingUid();
9772        int callingPid = Binder.getCallingPid();
9773        long ident = 0;
9774        boolean clearedIdentity = false;
9775        userId = unsafeConvertIncomingUser(userId);
9776        if (canClearIdentity(callingPid, callingUid, userId)) {
9777            clearedIdentity = true;
9778            ident = Binder.clearCallingIdentity();
9779        }
9780        ContentProviderHolder holder = null;
9781        try {
9782            holder = getContentProviderExternalUnchecked(name, null, userId);
9783            if (holder != null) {
9784                return holder.provider.getType(uri);
9785            }
9786        } catch (RemoteException e) {
9787            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9788            return null;
9789        } finally {
9790            // We need to clear the identity to call removeContentProviderExternalUnchecked
9791            if (!clearedIdentity) {
9792                ident = Binder.clearCallingIdentity();
9793            }
9794            try {
9795                if (holder != null) {
9796                    removeContentProviderExternalUnchecked(name, null, userId);
9797                }
9798            } finally {
9799                Binder.restoreCallingIdentity(ident);
9800            }
9801        }
9802
9803        return null;
9804    }
9805
9806    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9807        if (UserHandle.getUserId(callingUid) == userId) {
9808            return true;
9809        }
9810        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9811                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9812                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9813                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9814                return true;
9815        }
9816        return false;
9817    }
9818
9819    // =========================================================
9820    // GLOBAL MANAGEMENT
9821    // =========================================================
9822
9823    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9824            boolean isolated, int isolatedUid) {
9825        String proc = customProcess != null ? customProcess : info.processName;
9826        BatteryStatsImpl.Uid.Proc ps = null;
9827        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9828        int uid = info.uid;
9829        if (isolated) {
9830            if (isolatedUid == 0) {
9831                int userId = UserHandle.getUserId(uid);
9832                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9833                while (true) {
9834                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9835                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9836                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9837                    }
9838                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9839                    mNextIsolatedProcessUid++;
9840                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9841                        // No process for this uid, use it.
9842                        break;
9843                    }
9844                    stepsLeft--;
9845                    if (stepsLeft <= 0) {
9846                        return null;
9847                    }
9848                }
9849            } else {
9850                // Special case for startIsolatedProcess (internal only), where
9851                // the uid of the isolated process is specified by the caller.
9852                uid = isolatedUid;
9853            }
9854        }
9855        return new ProcessRecord(stats, info, proc, uid);
9856    }
9857
9858    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9859            String abiOverride) {
9860        ProcessRecord app;
9861        if (!isolated) {
9862            app = getProcessRecordLocked(info.processName, info.uid, true);
9863        } else {
9864            app = null;
9865        }
9866
9867        if (app == null) {
9868            app = newProcessRecordLocked(info, null, isolated, 0);
9869            mProcessNames.put(info.processName, app.uid, app);
9870            if (isolated) {
9871                mIsolatedProcesses.put(app.uid, app);
9872            }
9873            updateLruProcessLocked(app, false, null);
9874            updateOomAdjLocked();
9875        }
9876
9877        // This package really, really can not be stopped.
9878        try {
9879            AppGlobals.getPackageManager().setPackageStoppedState(
9880                    info.packageName, false, UserHandle.getUserId(app.uid));
9881        } catch (RemoteException e) {
9882        } catch (IllegalArgumentException e) {
9883            Slog.w(TAG, "Failed trying to unstop package "
9884                    + info.packageName + ": " + e);
9885        }
9886
9887        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9888                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9889            app.persistent = true;
9890            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9891        }
9892        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9893            mPersistentStartingProcesses.add(app);
9894            startProcessLocked(app, "added application", app.processName, abiOverride,
9895                    null /* entryPoint */, null /* entryPointArgs */);
9896        }
9897
9898        return app;
9899    }
9900
9901    public void unhandledBack() {
9902        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9903                "unhandledBack()");
9904
9905        synchronized(this) {
9906            final long origId = Binder.clearCallingIdentity();
9907            try {
9908                getFocusedStack().unhandledBackLocked();
9909            } finally {
9910                Binder.restoreCallingIdentity(origId);
9911            }
9912        }
9913    }
9914
9915    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9916        enforceNotIsolatedCaller("openContentUri");
9917        final int userId = UserHandle.getCallingUserId();
9918        String name = uri.getAuthority();
9919        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9920        ParcelFileDescriptor pfd = null;
9921        if (cph != null) {
9922            // We record the binder invoker's uid in thread-local storage before
9923            // going to the content provider to open the file.  Later, in the code
9924            // that handles all permissions checks, we look for this uid and use
9925            // that rather than the Activity Manager's own uid.  The effect is that
9926            // we do the check against the caller's permissions even though it looks
9927            // to the content provider like the Activity Manager itself is making
9928            // the request.
9929            sCallerIdentity.set(new Identity(
9930                    Binder.getCallingPid(), Binder.getCallingUid()));
9931            try {
9932                pfd = cph.provider.openFile(null, uri, "r", null);
9933            } catch (FileNotFoundException e) {
9934                // do nothing; pfd will be returned null
9935            } finally {
9936                // Ensure that whatever happens, we clean up the identity state
9937                sCallerIdentity.remove();
9938            }
9939
9940            // We've got the fd now, so we're done with the provider.
9941            removeContentProviderExternalUnchecked(name, null, userId);
9942        } else {
9943            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9944        }
9945        return pfd;
9946    }
9947
9948    // Actually is sleeping or shutting down or whatever else in the future
9949    // is an inactive state.
9950    public boolean isSleepingOrShuttingDown() {
9951        return isSleeping() || mShuttingDown;
9952    }
9953
9954    public boolean isSleeping() {
9955        return mSleeping && !mKeyguardWaitingForDraw;
9956    }
9957
9958    void goingToSleep() {
9959        synchronized(this) {
9960            mWentToSleep = true;
9961            updateEventDispatchingLocked();
9962            goToSleepIfNeededLocked();
9963        }
9964    }
9965
9966    void finishRunningVoiceLocked() {
9967        if (mRunningVoice) {
9968            mRunningVoice = false;
9969            goToSleepIfNeededLocked();
9970        }
9971    }
9972
9973    void goToSleepIfNeededLocked() {
9974        if (mWentToSleep && !mRunningVoice) {
9975            if (!mSleeping) {
9976                mSleeping = true;
9977                mKeyguardWaitingForDraw = false;
9978                mStackSupervisor.goingToSleepLocked();
9979
9980                // Initialize the wake times of all processes.
9981                checkExcessivePowerUsageLocked(false);
9982                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9983                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9984                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9985            }
9986        }
9987    }
9988
9989    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9990        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9991            // Never persist the home stack.
9992            return;
9993        }
9994        mTaskPersister.wakeup(task, flush);
9995    }
9996
9997    @Override
9998    public boolean shutdown(int timeout) {
9999        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10000                != PackageManager.PERMISSION_GRANTED) {
10001            throw new SecurityException("Requires permission "
10002                    + android.Manifest.permission.SHUTDOWN);
10003        }
10004
10005        boolean timedout = false;
10006
10007        synchronized(this) {
10008            mShuttingDown = true;
10009            updateEventDispatchingLocked();
10010            timedout = mStackSupervisor.shutdownLocked(timeout);
10011        }
10012
10013        mAppOpsService.shutdown();
10014        if (mUsageStatsService != null) {
10015            mUsageStatsService.prepareShutdown();
10016        }
10017        mBatteryStatsService.shutdown();
10018        synchronized (this) {
10019            mProcessStats.shutdownLocked();
10020        }
10021        notifyTaskPersisterLocked(null, true);
10022
10023        return timedout;
10024    }
10025
10026    public final void activitySlept(IBinder token) {
10027        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10028
10029        final long origId = Binder.clearCallingIdentity();
10030
10031        synchronized (this) {
10032            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10033            if (r != null) {
10034                mStackSupervisor.activitySleptLocked(r);
10035            }
10036        }
10037
10038        Binder.restoreCallingIdentity(origId);
10039    }
10040
10041    void logLockScreen(String msg) {
10042        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10043                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10044                mWentToSleep + " mSleeping=" + mSleeping);
10045    }
10046
10047    private void comeOutOfSleepIfNeededLocked() {
10048        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10049            if (mSleeping) {
10050                mSleeping = false;
10051                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10052            }
10053        }
10054    }
10055
10056    void wakingUp() {
10057        synchronized(this) {
10058            mWentToSleep = false;
10059            updateEventDispatchingLocked();
10060            comeOutOfSleepIfNeededLocked();
10061        }
10062    }
10063
10064    void startRunningVoiceLocked() {
10065        if (!mRunningVoice) {
10066            mRunningVoice = true;
10067            comeOutOfSleepIfNeededLocked();
10068        }
10069    }
10070
10071    private void updateEventDispatchingLocked() {
10072        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10073    }
10074
10075    public void setLockScreenShown(boolean shown) {
10076        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10077                != PackageManager.PERMISSION_GRANTED) {
10078            throw new SecurityException("Requires permission "
10079                    + android.Manifest.permission.DEVICE_POWER);
10080        }
10081
10082        synchronized(this) {
10083            long ident = Binder.clearCallingIdentity();
10084            try {
10085                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10086                mLockScreenShown = shown;
10087                mKeyguardWaitingForDraw = false;
10088                comeOutOfSleepIfNeededLocked();
10089            } finally {
10090                Binder.restoreCallingIdentity(ident);
10091            }
10092        }
10093    }
10094
10095    @Override
10096    public void stopAppSwitches() {
10097        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10098                != PackageManager.PERMISSION_GRANTED) {
10099            throw new SecurityException("Requires permission "
10100                    + android.Manifest.permission.STOP_APP_SWITCHES);
10101        }
10102
10103        synchronized(this) {
10104            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10105                    + APP_SWITCH_DELAY_TIME;
10106            mDidAppSwitch = false;
10107            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10108            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10109            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10110        }
10111    }
10112
10113    public void resumeAppSwitches() {
10114        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10115                != PackageManager.PERMISSION_GRANTED) {
10116            throw new SecurityException("Requires permission "
10117                    + android.Manifest.permission.STOP_APP_SWITCHES);
10118        }
10119
10120        synchronized(this) {
10121            // Note that we don't execute any pending app switches... we will
10122            // let those wait until either the timeout, or the next start
10123            // activity request.
10124            mAppSwitchesAllowedTime = 0;
10125        }
10126    }
10127
10128    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10129            int callingPid, int callingUid, String name) {
10130        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10131            return true;
10132        }
10133
10134        int perm = checkComponentPermission(
10135                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10136                sourceUid, -1, true);
10137        if (perm == PackageManager.PERMISSION_GRANTED) {
10138            return true;
10139        }
10140
10141        // If the actual IPC caller is different from the logical source, then
10142        // also see if they are allowed to control app switches.
10143        if (callingUid != -1 && callingUid != sourceUid) {
10144            perm = checkComponentPermission(
10145                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10146                    callingUid, -1, true);
10147            if (perm == PackageManager.PERMISSION_GRANTED) {
10148                return true;
10149            }
10150        }
10151
10152        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10153        return false;
10154    }
10155
10156    public void setDebugApp(String packageName, boolean waitForDebugger,
10157            boolean persistent) {
10158        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10159                "setDebugApp()");
10160
10161        long ident = Binder.clearCallingIdentity();
10162        try {
10163            // Note that this is not really thread safe if there are multiple
10164            // callers into it at the same time, but that's not a situation we
10165            // care about.
10166            if (persistent) {
10167                final ContentResolver resolver = mContext.getContentResolver();
10168                Settings.Global.putString(
10169                    resolver, Settings.Global.DEBUG_APP,
10170                    packageName);
10171                Settings.Global.putInt(
10172                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10173                    waitForDebugger ? 1 : 0);
10174            }
10175
10176            synchronized (this) {
10177                if (!persistent) {
10178                    mOrigDebugApp = mDebugApp;
10179                    mOrigWaitForDebugger = mWaitForDebugger;
10180                }
10181                mDebugApp = packageName;
10182                mWaitForDebugger = waitForDebugger;
10183                mDebugTransient = !persistent;
10184                if (packageName != null) {
10185                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10186                            false, UserHandle.USER_ALL, "set debug app");
10187                }
10188            }
10189        } finally {
10190            Binder.restoreCallingIdentity(ident);
10191        }
10192    }
10193
10194    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10195        synchronized (this) {
10196            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10197            if (!isDebuggable) {
10198                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10199                    throw new SecurityException("Process not debuggable: " + app.packageName);
10200                }
10201            }
10202
10203            mOpenGlTraceApp = processName;
10204        }
10205    }
10206
10207    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10208        synchronized (this) {
10209            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10210            if (!isDebuggable) {
10211                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10212                    throw new SecurityException("Process not debuggable: " + app.packageName);
10213                }
10214            }
10215            mProfileApp = processName;
10216            mProfileFile = profilerInfo.profileFile;
10217            if (mProfileFd != null) {
10218                try {
10219                    mProfileFd.close();
10220                } catch (IOException e) {
10221                }
10222                mProfileFd = null;
10223            }
10224            mProfileFd = profilerInfo.profileFd;
10225            mSamplingInterval = profilerInfo.samplingInterval;
10226            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10227            mProfileType = 0;
10228        }
10229    }
10230
10231    @Override
10232    public void setAlwaysFinish(boolean enabled) {
10233        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10234                "setAlwaysFinish()");
10235
10236        Settings.Global.putInt(
10237                mContext.getContentResolver(),
10238                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10239
10240        synchronized (this) {
10241            mAlwaysFinishActivities = enabled;
10242        }
10243    }
10244
10245    @Override
10246    public void setActivityController(IActivityController controller) {
10247        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10248                "setActivityController()");
10249        synchronized (this) {
10250            mController = controller;
10251            Watchdog.getInstance().setActivityController(controller);
10252        }
10253    }
10254
10255    @Override
10256    public void setUserIsMonkey(boolean userIsMonkey) {
10257        synchronized (this) {
10258            synchronized (mPidsSelfLocked) {
10259                final int callingPid = Binder.getCallingPid();
10260                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10261                if (precessRecord == null) {
10262                    throw new SecurityException("Unknown process: " + callingPid);
10263                }
10264                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10265                    throw new SecurityException("Only an instrumentation process "
10266                            + "with a UiAutomation can call setUserIsMonkey");
10267                }
10268            }
10269            mUserIsMonkey = userIsMonkey;
10270        }
10271    }
10272
10273    @Override
10274    public boolean isUserAMonkey() {
10275        synchronized (this) {
10276            // If there is a controller also implies the user is a monkey.
10277            return (mUserIsMonkey || mController != null);
10278        }
10279    }
10280
10281    public void requestBugReport() {
10282        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10283        SystemProperties.set("ctl.start", "bugreport");
10284    }
10285
10286    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10287        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10288    }
10289
10290    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10291        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10292            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10293        }
10294        return KEY_DISPATCHING_TIMEOUT;
10295    }
10296
10297    @Override
10298    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10299        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10300                != PackageManager.PERMISSION_GRANTED) {
10301            throw new SecurityException("Requires permission "
10302                    + android.Manifest.permission.FILTER_EVENTS);
10303        }
10304        ProcessRecord proc;
10305        long timeout;
10306        synchronized (this) {
10307            synchronized (mPidsSelfLocked) {
10308                proc = mPidsSelfLocked.get(pid);
10309            }
10310            timeout = getInputDispatchingTimeoutLocked(proc);
10311        }
10312
10313        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10314            return -1;
10315        }
10316
10317        return timeout;
10318    }
10319
10320    /**
10321     * Handle input dispatching timeouts.
10322     * Returns whether input dispatching should be aborted or not.
10323     */
10324    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10325            final ActivityRecord activity, final ActivityRecord parent,
10326            final boolean aboveSystem, String reason) {
10327        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10328                != PackageManager.PERMISSION_GRANTED) {
10329            throw new SecurityException("Requires permission "
10330                    + android.Manifest.permission.FILTER_EVENTS);
10331        }
10332
10333        final String annotation;
10334        if (reason == null) {
10335            annotation = "Input dispatching timed out";
10336        } else {
10337            annotation = "Input dispatching timed out (" + reason + ")";
10338        }
10339
10340        if (proc != null) {
10341            synchronized (this) {
10342                if (proc.debugging) {
10343                    return false;
10344                }
10345
10346                if (mDidDexOpt) {
10347                    // Give more time since we were dexopting.
10348                    mDidDexOpt = false;
10349                    return false;
10350                }
10351
10352                if (proc.instrumentationClass != null) {
10353                    Bundle info = new Bundle();
10354                    info.putString("shortMsg", "keyDispatchingTimedOut");
10355                    info.putString("longMsg", annotation);
10356                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10357                    return true;
10358                }
10359            }
10360            mHandler.post(new Runnable() {
10361                @Override
10362                public void run() {
10363                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10364                }
10365            });
10366        }
10367
10368        return true;
10369    }
10370
10371    public Bundle getAssistContextExtras(int requestType) {
10372        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10373                "getAssistContextExtras()");
10374        PendingAssistExtras pae;
10375        Bundle extras = new Bundle();
10376        synchronized (this) {
10377            ActivityRecord activity = getFocusedStack().mResumedActivity;
10378            if (activity == null) {
10379                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10380                return null;
10381            }
10382            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10383            if (activity.app == null || activity.app.thread == null) {
10384                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10385                return extras;
10386            }
10387            if (activity.app.pid == Binder.getCallingPid()) {
10388                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10389                return extras;
10390            }
10391            pae = new PendingAssistExtras(activity);
10392            try {
10393                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10394                        requestType);
10395                mPendingAssistExtras.add(pae);
10396                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10397            } catch (RemoteException e) {
10398                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10399                return extras;
10400            }
10401        }
10402        synchronized (pae) {
10403            while (!pae.haveResult) {
10404                try {
10405                    pae.wait();
10406                } catch (InterruptedException e) {
10407                }
10408            }
10409            if (pae.result != null) {
10410                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10411            }
10412        }
10413        synchronized (this) {
10414            mPendingAssistExtras.remove(pae);
10415            mHandler.removeCallbacks(pae);
10416        }
10417        return extras;
10418    }
10419
10420    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10421        PendingAssistExtras pae = (PendingAssistExtras)token;
10422        synchronized (pae) {
10423            pae.result = extras;
10424            pae.haveResult = true;
10425            pae.notifyAll();
10426        }
10427    }
10428
10429    public void registerProcessObserver(IProcessObserver observer) {
10430        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10431                "registerProcessObserver()");
10432        synchronized (this) {
10433            mProcessObservers.register(observer);
10434        }
10435    }
10436
10437    @Override
10438    public void unregisterProcessObserver(IProcessObserver observer) {
10439        synchronized (this) {
10440            mProcessObservers.unregister(observer);
10441        }
10442    }
10443
10444    @Override
10445    public boolean convertFromTranslucent(IBinder token) {
10446        final long origId = Binder.clearCallingIdentity();
10447        try {
10448            synchronized (this) {
10449                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10450                if (r == null) {
10451                    return false;
10452                }
10453                final boolean translucentChanged = r.changeWindowTranslucency(true);
10454                if (translucentChanged) {
10455                    r.task.stack.releaseBackgroundResources();
10456                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10457                }
10458                mWindowManager.setAppFullscreen(token, true);
10459                return translucentChanged;
10460            }
10461        } finally {
10462            Binder.restoreCallingIdentity(origId);
10463        }
10464    }
10465
10466    @Override
10467    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10468        final long origId = Binder.clearCallingIdentity();
10469        try {
10470            synchronized (this) {
10471                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10472                if (r == null) {
10473                    return false;
10474                }
10475                int index = r.task.mActivities.lastIndexOf(r);
10476                if (index > 0) {
10477                    ActivityRecord under = r.task.mActivities.get(index - 1);
10478                    under.returningOptions = options;
10479                }
10480                final boolean translucentChanged = r.changeWindowTranslucency(false);
10481                if (translucentChanged) {
10482                    r.task.stack.convertToTranslucent(r);
10483                }
10484                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10485                mWindowManager.setAppFullscreen(token, false);
10486                return translucentChanged;
10487            }
10488        } finally {
10489            Binder.restoreCallingIdentity(origId);
10490        }
10491    }
10492
10493    @Override
10494    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10495        final long origId = Binder.clearCallingIdentity();
10496        try {
10497            synchronized (this) {
10498                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10499                if (r != null) {
10500                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10501                }
10502            }
10503            return false;
10504        } finally {
10505            Binder.restoreCallingIdentity(origId);
10506        }
10507    }
10508
10509    @Override
10510    public boolean isBackgroundVisibleBehind(IBinder token) {
10511        final long origId = Binder.clearCallingIdentity();
10512        try {
10513            synchronized (this) {
10514                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10515                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10516                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10517                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10518                return visible;
10519            }
10520        } finally {
10521            Binder.restoreCallingIdentity(origId);
10522        }
10523    }
10524
10525    @Override
10526    public ActivityOptions getActivityOptions(IBinder token) {
10527        final long origId = Binder.clearCallingIdentity();
10528        try {
10529            synchronized (this) {
10530                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10531                if (r != null) {
10532                    final ActivityOptions activityOptions = r.pendingOptions;
10533                    r.pendingOptions = null;
10534                    return activityOptions;
10535                }
10536                return null;
10537            }
10538        } finally {
10539            Binder.restoreCallingIdentity(origId);
10540        }
10541    }
10542
10543    @Override
10544    public void setImmersive(IBinder token, boolean immersive) {
10545        synchronized(this) {
10546            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10547            if (r == null) {
10548                throw new IllegalArgumentException();
10549            }
10550            r.immersive = immersive;
10551
10552            // update associated state if we're frontmost
10553            if (r == mFocusedActivity) {
10554                if (DEBUG_IMMERSIVE) {
10555                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10556                }
10557                applyUpdateLockStateLocked(r);
10558            }
10559        }
10560    }
10561
10562    @Override
10563    public boolean isImmersive(IBinder token) {
10564        synchronized (this) {
10565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10566            if (r == null) {
10567                throw new IllegalArgumentException();
10568            }
10569            return r.immersive;
10570        }
10571    }
10572
10573    public boolean isTopActivityImmersive() {
10574        enforceNotIsolatedCaller("startActivity");
10575        synchronized (this) {
10576            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10577            return (r != null) ? r.immersive : false;
10578        }
10579    }
10580
10581    @Override
10582    public boolean isTopOfTask(IBinder token) {
10583        synchronized (this) {
10584            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10585            if (r == null) {
10586                throw new IllegalArgumentException();
10587            }
10588            return r.task.getTopActivity() == r;
10589        }
10590    }
10591
10592    public final void enterSafeMode() {
10593        synchronized(this) {
10594            // It only makes sense to do this before the system is ready
10595            // and started launching other packages.
10596            if (!mSystemReady) {
10597                try {
10598                    AppGlobals.getPackageManager().enterSafeMode();
10599                } catch (RemoteException e) {
10600                }
10601            }
10602
10603            mSafeMode = true;
10604        }
10605    }
10606
10607    public final void showSafeModeOverlay() {
10608        View v = LayoutInflater.from(mContext).inflate(
10609                com.android.internal.R.layout.safe_mode, null);
10610        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10611        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10612        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10613        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10614        lp.gravity = Gravity.BOTTOM | Gravity.START;
10615        lp.format = v.getBackground().getOpacity();
10616        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10617                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10618        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10619        ((WindowManager)mContext.getSystemService(
10620                Context.WINDOW_SERVICE)).addView(v, lp);
10621    }
10622
10623    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10624        if (!(sender instanceof PendingIntentRecord)) {
10625            return;
10626        }
10627        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10628        synchronized (stats) {
10629            if (mBatteryStatsService.isOnBattery()) {
10630                mBatteryStatsService.enforceCallingPermission();
10631                PendingIntentRecord rec = (PendingIntentRecord)sender;
10632                int MY_UID = Binder.getCallingUid();
10633                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10634                BatteryStatsImpl.Uid.Pkg pkg =
10635                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10636                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10637                pkg.incWakeupsLocked();
10638            }
10639        }
10640    }
10641
10642    public boolean killPids(int[] pids, String pReason, boolean secure) {
10643        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10644            throw new SecurityException("killPids only available to the system");
10645        }
10646        String reason = (pReason == null) ? "Unknown" : pReason;
10647        // XXX Note: don't acquire main activity lock here, because the window
10648        // manager calls in with its locks held.
10649
10650        boolean killed = false;
10651        synchronized (mPidsSelfLocked) {
10652            int[] types = new int[pids.length];
10653            int worstType = 0;
10654            for (int i=0; i<pids.length; i++) {
10655                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10656                if (proc != null) {
10657                    int type = proc.setAdj;
10658                    types[i] = type;
10659                    if (type > worstType) {
10660                        worstType = type;
10661                    }
10662                }
10663            }
10664
10665            // If the worst oom_adj is somewhere in the cached proc LRU range,
10666            // then constrain it so we will kill all cached procs.
10667            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10668                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10669                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10670            }
10671
10672            // If this is not a secure call, don't let it kill processes that
10673            // are important.
10674            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10675                worstType = ProcessList.SERVICE_ADJ;
10676            }
10677
10678            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10679            for (int i=0; i<pids.length; i++) {
10680                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10681                if (proc == null) {
10682                    continue;
10683                }
10684                int adj = proc.setAdj;
10685                if (adj >= worstType && !proc.killedByAm) {
10686                    proc.kill(reason, true);
10687                    killed = true;
10688                }
10689            }
10690        }
10691        return killed;
10692    }
10693
10694    @Override
10695    public void killUid(int uid, String reason) {
10696        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10697            throw new SecurityException("killUid only available to the system");
10698        }
10699        synchronized (this) {
10700            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10701                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10702                    reason != null ? reason : "kill uid");
10703        }
10704    }
10705
10706    @Override
10707    public boolean killProcessesBelowForeground(String reason) {
10708        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10709            throw new SecurityException("killProcessesBelowForeground() only available to system");
10710        }
10711
10712        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10713    }
10714
10715    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10716        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10717            throw new SecurityException("killProcessesBelowAdj() only available to system");
10718        }
10719
10720        boolean killed = false;
10721        synchronized (mPidsSelfLocked) {
10722            final int size = mPidsSelfLocked.size();
10723            for (int i = 0; i < size; i++) {
10724                final int pid = mPidsSelfLocked.keyAt(i);
10725                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10726                if (proc == null) continue;
10727
10728                final int adj = proc.setAdj;
10729                if (adj > belowAdj && !proc.killedByAm) {
10730                    proc.kill(reason, true);
10731                    killed = true;
10732                }
10733            }
10734        }
10735        return killed;
10736    }
10737
10738    @Override
10739    public void hang(final IBinder who, boolean allowRestart) {
10740        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10741                != PackageManager.PERMISSION_GRANTED) {
10742            throw new SecurityException("Requires permission "
10743                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10744        }
10745
10746        final IBinder.DeathRecipient death = new DeathRecipient() {
10747            @Override
10748            public void binderDied() {
10749                synchronized (this) {
10750                    notifyAll();
10751                }
10752            }
10753        };
10754
10755        try {
10756            who.linkToDeath(death, 0);
10757        } catch (RemoteException e) {
10758            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10759            return;
10760        }
10761
10762        synchronized (this) {
10763            Watchdog.getInstance().setAllowRestart(allowRestart);
10764            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10765            synchronized (death) {
10766                while (who.isBinderAlive()) {
10767                    try {
10768                        death.wait();
10769                    } catch (InterruptedException e) {
10770                    }
10771                }
10772            }
10773            Watchdog.getInstance().setAllowRestart(true);
10774        }
10775    }
10776
10777    @Override
10778    public void restart() {
10779        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10780                != PackageManager.PERMISSION_GRANTED) {
10781            throw new SecurityException("Requires permission "
10782                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10783        }
10784
10785        Log.i(TAG, "Sending shutdown broadcast...");
10786
10787        BroadcastReceiver br = new BroadcastReceiver() {
10788            @Override public void onReceive(Context context, Intent intent) {
10789                // Now the broadcast is done, finish up the low-level shutdown.
10790                Log.i(TAG, "Shutting down activity manager...");
10791                shutdown(10000);
10792                Log.i(TAG, "Shutdown complete, restarting!");
10793                Process.killProcess(Process.myPid());
10794                System.exit(10);
10795            }
10796        };
10797
10798        // First send the high-level shut down broadcast.
10799        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10800        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10801        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10802        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10803        mContext.sendOrderedBroadcastAsUser(intent,
10804                UserHandle.ALL, null, br, mHandler, 0, null, null);
10805        */
10806        br.onReceive(mContext, intent);
10807    }
10808
10809    private long getLowRamTimeSinceIdle(long now) {
10810        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10811    }
10812
10813    @Override
10814    public void performIdleMaintenance() {
10815        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10816                != PackageManager.PERMISSION_GRANTED) {
10817            throw new SecurityException("Requires permission "
10818                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10819        }
10820
10821        synchronized (this) {
10822            final long now = SystemClock.uptimeMillis();
10823            final long timeSinceLastIdle = now - mLastIdleTime;
10824            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10825            mLastIdleTime = now;
10826            mLowRamTimeSinceLastIdle = 0;
10827            if (mLowRamStartTime != 0) {
10828                mLowRamStartTime = now;
10829            }
10830
10831            StringBuilder sb = new StringBuilder(128);
10832            sb.append("Idle maintenance over ");
10833            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10834            sb.append(" low RAM for ");
10835            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10836            Slog.i(TAG, sb.toString());
10837
10838            // If at least 1/3 of our time since the last idle period has been spent
10839            // with RAM low, then we want to kill processes.
10840            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10841
10842            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10843                ProcessRecord proc = mLruProcesses.get(i);
10844                if (proc.notCachedSinceIdle) {
10845                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10846                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10847                        if (doKilling && proc.initialIdlePss != 0
10848                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10849                            proc.kill("idle maint (pss " + proc.lastPss
10850                                    + " from " + proc.initialIdlePss + ")", true);
10851                        }
10852                    }
10853                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10854                    proc.notCachedSinceIdle = true;
10855                    proc.initialIdlePss = 0;
10856                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10857                            isSleeping(), now);
10858                }
10859            }
10860
10861            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10862            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10863        }
10864    }
10865
10866    private void retrieveSettings() {
10867        final ContentResolver resolver = mContext.getContentResolver();
10868        String debugApp = Settings.Global.getString(
10869            resolver, Settings.Global.DEBUG_APP);
10870        boolean waitForDebugger = Settings.Global.getInt(
10871            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10872        boolean alwaysFinishActivities = Settings.Global.getInt(
10873            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10874        boolean forceRtl = Settings.Global.getInt(
10875                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10876        // Transfer any global setting for forcing RTL layout, into a System Property
10877        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10878
10879        Configuration configuration = new Configuration();
10880        Settings.System.getConfiguration(resolver, configuration);
10881        if (forceRtl) {
10882            // This will take care of setting the correct layout direction flags
10883            configuration.setLayoutDirection(configuration.locale);
10884        }
10885
10886        synchronized (this) {
10887            mDebugApp = mOrigDebugApp = debugApp;
10888            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10889            mAlwaysFinishActivities = alwaysFinishActivities;
10890            // This happens before any activities are started, so we can
10891            // change mConfiguration in-place.
10892            updateConfigurationLocked(configuration, null, false, true);
10893            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10894        }
10895    }
10896
10897    /** Loads resources after the current configuration has been set. */
10898    private void loadResourcesOnSystemReady() {
10899        final Resources res = mContext.getResources();
10900        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10901        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10902        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10903    }
10904
10905    public boolean testIsSystemReady() {
10906        // no need to synchronize(this) just to read & return the value
10907        return mSystemReady;
10908    }
10909
10910    private static File getCalledPreBootReceiversFile() {
10911        File dataDir = Environment.getDataDirectory();
10912        File systemDir = new File(dataDir, "system");
10913        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10914        return fname;
10915    }
10916
10917    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10918        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10919        File file = getCalledPreBootReceiversFile();
10920        FileInputStream fis = null;
10921        try {
10922            fis = new FileInputStream(file);
10923            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10924            int fvers = dis.readInt();
10925            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10926                String vers = dis.readUTF();
10927                String codename = dis.readUTF();
10928                String build = dis.readUTF();
10929                if (android.os.Build.VERSION.RELEASE.equals(vers)
10930                        && android.os.Build.VERSION.CODENAME.equals(codename)
10931                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10932                    int num = dis.readInt();
10933                    while (num > 0) {
10934                        num--;
10935                        String pkg = dis.readUTF();
10936                        String cls = dis.readUTF();
10937                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10938                    }
10939                }
10940            }
10941        } catch (FileNotFoundException e) {
10942        } catch (IOException e) {
10943            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10944        } finally {
10945            if (fis != null) {
10946                try {
10947                    fis.close();
10948                } catch (IOException e) {
10949                }
10950            }
10951        }
10952        return lastDoneReceivers;
10953    }
10954
10955    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10956        File file = getCalledPreBootReceiversFile();
10957        FileOutputStream fos = null;
10958        DataOutputStream dos = null;
10959        try {
10960            fos = new FileOutputStream(file);
10961            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10962            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10963            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10964            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10965            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10966            dos.writeInt(list.size());
10967            for (int i=0; i<list.size(); i++) {
10968                dos.writeUTF(list.get(i).getPackageName());
10969                dos.writeUTF(list.get(i).getClassName());
10970            }
10971        } catch (IOException e) {
10972            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10973            file.delete();
10974        } finally {
10975            FileUtils.sync(fos);
10976            if (dos != null) {
10977                try {
10978                    dos.close();
10979                } catch (IOException e) {
10980                    // TODO Auto-generated catch block
10981                    e.printStackTrace();
10982                }
10983            }
10984        }
10985    }
10986
10987    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10988            ArrayList<ComponentName> doneReceivers, int userId) {
10989        boolean waitingUpdate = false;
10990        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10991        List<ResolveInfo> ris = null;
10992        try {
10993            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10994                    intent, null, 0, userId);
10995        } catch (RemoteException e) {
10996        }
10997        if (ris != null) {
10998            for (int i=ris.size()-1; i>=0; i--) {
10999                if ((ris.get(i).activityInfo.applicationInfo.flags
11000                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11001                    ris.remove(i);
11002                }
11003            }
11004            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11005
11006            // For User 0, load the version number. When delivering to a new user, deliver
11007            // to all receivers.
11008            if (userId == UserHandle.USER_OWNER) {
11009                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11010                for (int i=0; i<ris.size(); i++) {
11011                    ActivityInfo ai = ris.get(i).activityInfo;
11012                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11013                    if (lastDoneReceivers.contains(comp)) {
11014                        // We already did the pre boot receiver for this app with the current
11015                        // platform version, so don't do it again...
11016                        ris.remove(i);
11017                        i--;
11018                        // ...however, do keep it as one that has been done, so we don't
11019                        // forget about it when rewriting the file of last done receivers.
11020                        doneReceivers.add(comp);
11021                    }
11022                }
11023            }
11024
11025            // If primary user, send broadcast to all available users, else just to userId
11026            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11027                    : new int[] { userId };
11028            for (int i = 0; i < ris.size(); i++) {
11029                ActivityInfo ai = ris.get(i).activityInfo;
11030                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11031                doneReceivers.add(comp);
11032                intent.setComponent(comp);
11033                for (int j=0; j<users.length; j++) {
11034                    IIntentReceiver finisher = null;
11035                    // On last receiver and user, set up a completion callback
11036                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11037                        finisher = new IIntentReceiver.Stub() {
11038                            public void performReceive(Intent intent, int resultCode,
11039                                    String data, Bundle extras, boolean ordered,
11040                                    boolean sticky, int sendingUser) {
11041                                // The raw IIntentReceiver interface is called
11042                                // with the AM lock held, so redispatch to
11043                                // execute our code without the lock.
11044                                mHandler.post(onFinishCallback);
11045                            }
11046                        };
11047                    }
11048                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11049                            + " for user " + users[j]);
11050                    broadcastIntentLocked(null, null, intent, null, finisher,
11051                            0, null, null, null, AppOpsManager.OP_NONE,
11052                            true, false, MY_PID, Process.SYSTEM_UID,
11053                            users[j]);
11054                    if (finisher != null) {
11055                        waitingUpdate = true;
11056                    }
11057                }
11058            }
11059        }
11060
11061        return waitingUpdate;
11062    }
11063
11064    public void systemReady(final Runnable goingCallback) {
11065        synchronized(this) {
11066            if (mSystemReady) {
11067                // If we're done calling all the receivers, run the next "boot phase" passed in
11068                // by the SystemServer
11069                if (goingCallback != null) {
11070                    goingCallback.run();
11071                }
11072                return;
11073            }
11074
11075            // Make sure we have the current profile info, since it is needed for
11076            // security checks.
11077            updateCurrentProfileIdsLocked();
11078
11079            if (mRecentTasks == null) {
11080                mRecentTasks = mTaskPersister.restoreTasksLocked();
11081                if (!mRecentTasks.isEmpty()) {
11082                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11083                }
11084                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11085                mTaskPersister.startPersisting();
11086            }
11087
11088            // Check to see if there are any update receivers to run.
11089            if (!mDidUpdate) {
11090                if (mWaitingUpdate) {
11091                    return;
11092                }
11093                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11094                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11095                    public void run() {
11096                        synchronized (ActivityManagerService.this) {
11097                            mDidUpdate = true;
11098                        }
11099                        writeLastDonePreBootReceivers(doneReceivers);
11100                        showBootMessage(mContext.getText(
11101                                R.string.android_upgrading_complete),
11102                                false);
11103                        systemReady(goingCallback);
11104                    }
11105                }, doneReceivers, UserHandle.USER_OWNER);
11106
11107                if (mWaitingUpdate) {
11108                    return;
11109                }
11110                mDidUpdate = true;
11111            }
11112
11113            mAppOpsService.systemReady();
11114            mSystemReady = true;
11115        }
11116
11117        ArrayList<ProcessRecord> procsToKill = null;
11118        synchronized(mPidsSelfLocked) {
11119            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11120                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11121                if (!isAllowedWhileBooting(proc.info)){
11122                    if (procsToKill == null) {
11123                        procsToKill = new ArrayList<ProcessRecord>();
11124                    }
11125                    procsToKill.add(proc);
11126                }
11127            }
11128        }
11129
11130        synchronized(this) {
11131            if (procsToKill != null) {
11132                for (int i=procsToKill.size()-1; i>=0; i--) {
11133                    ProcessRecord proc = procsToKill.get(i);
11134                    Slog.i(TAG, "Removing system update proc: " + proc);
11135                    removeProcessLocked(proc, true, false, "system update done");
11136                }
11137            }
11138
11139            // Now that we have cleaned up any update processes, we
11140            // are ready to start launching real processes and know that
11141            // we won't trample on them any more.
11142            mProcessesReady = true;
11143        }
11144
11145        Slog.i(TAG, "System now ready");
11146        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11147            SystemClock.uptimeMillis());
11148
11149        synchronized(this) {
11150            // Make sure we have no pre-ready processes sitting around.
11151
11152            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11153                ResolveInfo ri = mContext.getPackageManager()
11154                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11155                                STOCK_PM_FLAGS);
11156                CharSequence errorMsg = null;
11157                if (ri != null) {
11158                    ActivityInfo ai = ri.activityInfo;
11159                    ApplicationInfo app = ai.applicationInfo;
11160                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11161                        mTopAction = Intent.ACTION_FACTORY_TEST;
11162                        mTopData = null;
11163                        mTopComponent = new ComponentName(app.packageName,
11164                                ai.name);
11165                    } else {
11166                        errorMsg = mContext.getResources().getText(
11167                                com.android.internal.R.string.factorytest_not_system);
11168                    }
11169                } else {
11170                    errorMsg = mContext.getResources().getText(
11171                            com.android.internal.R.string.factorytest_no_action);
11172                }
11173                if (errorMsg != null) {
11174                    mTopAction = null;
11175                    mTopData = null;
11176                    mTopComponent = null;
11177                    Message msg = Message.obtain();
11178                    msg.what = SHOW_FACTORY_ERROR_MSG;
11179                    msg.getData().putCharSequence("msg", errorMsg);
11180                    mHandler.sendMessage(msg);
11181                }
11182            }
11183        }
11184
11185        retrieveSettings();
11186        loadResourcesOnSystemReady();
11187
11188        synchronized (this) {
11189            readGrantedUriPermissionsLocked();
11190        }
11191
11192        if (goingCallback != null) goingCallback.run();
11193
11194        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11195                Integer.toString(mCurrentUserId), mCurrentUserId);
11196        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11197                Integer.toString(mCurrentUserId), mCurrentUserId);
11198        mSystemServiceManager.startUser(mCurrentUserId);
11199
11200        synchronized (this) {
11201            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11202                try {
11203                    List apps = AppGlobals.getPackageManager().
11204                        getPersistentApplications(STOCK_PM_FLAGS);
11205                    if (apps != null) {
11206                        int N = apps.size();
11207                        int i;
11208                        for (i=0; i<N; i++) {
11209                            ApplicationInfo info
11210                                = (ApplicationInfo)apps.get(i);
11211                            if (info != null &&
11212                                    !info.packageName.equals("android")) {
11213                                addAppLocked(info, false, null /* ABI override */);
11214                            }
11215                        }
11216                    }
11217                } catch (RemoteException ex) {
11218                    // pm is in same process, this will never happen.
11219                }
11220            }
11221
11222            // Start up initial activity.
11223            mBooting = true;
11224
11225            try {
11226                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11227                    Message msg = Message.obtain();
11228                    msg.what = SHOW_UID_ERROR_MSG;
11229                    mHandler.sendMessage(msg);
11230                }
11231            } catch (RemoteException e) {
11232            }
11233
11234            long ident = Binder.clearCallingIdentity();
11235            try {
11236                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11237                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11238                        | Intent.FLAG_RECEIVER_FOREGROUND);
11239                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11240                broadcastIntentLocked(null, null, intent,
11241                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11242                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11243                intent = new Intent(Intent.ACTION_USER_STARTING);
11244                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11245                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11246                broadcastIntentLocked(null, null, intent,
11247                        null, new IIntentReceiver.Stub() {
11248                            @Override
11249                            public void performReceive(Intent intent, int resultCode, String data,
11250                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11251                                    throws RemoteException {
11252                            }
11253                        }, 0, null, null,
11254                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11255                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11256            } catch (Throwable t) {
11257                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11258            } finally {
11259                Binder.restoreCallingIdentity(ident);
11260            }
11261            mStackSupervisor.resumeTopActivitiesLocked();
11262            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11263        }
11264    }
11265
11266    private boolean makeAppCrashingLocked(ProcessRecord app,
11267            String shortMsg, String longMsg, String stackTrace) {
11268        app.crashing = true;
11269        app.crashingReport = generateProcessError(app,
11270                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11271        startAppProblemLocked(app);
11272        app.stopFreezingAllLocked();
11273        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11274    }
11275
11276    private void makeAppNotRespondingLocked(ProcessRecord app,
11277            String activity, String shortMsg, String longMsg) {
11278        app.notResponding = true;
11279        app.notRespondingReport = generateProcessError(app,
11280                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11281                activity, shortMsg, longMsg, null);
11282        startAppProblemLocked(app);
11283        app.stopFreezingAllLocked();
11284    }
11285
11286    /**
11287     * Generate a process error record, suitable for attachment to a ProcessRecord.
11288     *
11289     * @param app The ProcessRecord in which the error occurred.
11290     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11291     *                      ActivityManager.AppErrorStateInfo
11292     * @param activity The activity associated with the crash, if known.
11293     * @param shortMsg Short message describing the crash.
11294     * @param longMsg Long message describing the crash.
11295     * @param stackTrace Full crash stack trace, may be null.
11296     *
11297     * @return Returns a fully-formed AppErrorStateInfo record.
11298     */
11299    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11300            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11301        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11302
11303        report.condition = condition;
11304        report.processName = app.processName;
11305        report.pid = app.pid;
11306        report.uid = app.info.uid;
11307        report.tag = activity;
11308        report.shortMsg = shortMsg;
11309        report.longMsg = longMsg;
11310        report.stackTrace = stackTrace;
11311
11312        return report;
11313    }
11314
11315    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11316        synchronized (this) {
11317            app.crashing = false;
11318            app.crashingReport = null;
11319            app.notResponding = false;
11320            app.notRespondingReport = null;
11321            if (app.anrDialog == fromDialog) {
11322                app.anrDialog = null;
11323            }
11324            if (app.waitDialog == fromDialog) {
11325                app.waitDialog = null;
11326            }
11327            if (app.pid > 0 && app.pid != MY_PID) {
11328                handleAppCrashLocked(app, null, null, null);
11329                app.kill("user request after error", true);
11330            }
11331        }
11332    }
11333
11334    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11335            String stackTrace) {
11336        long now = SystemClock.uptimeMillis();
11337
11338        Long crashTime;
11339        if (!app.isolated) {
11340            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11341        } else {
11342            crashTime = null;
11343        }
11344        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11345            // This process loses!
11346            Slog.w(TAG, "Process " + app.info.processName
11347                    + " has crashed too many times: killing!");
11348            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11349                    app.userId, app.info.processName, app.uid);
11350            mStackSupervisor.handleAppCrashLocked(app);
11351            if (!app.persistent) {
11352                // We don't want to start this process again until the user
11353                // explicitly does so...  but for persistent process, we really
11354                // need to keep it running.  If a persistent process is actually
11355                // repeatedly crashing, then badness for everyone.
11356                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11357                        app.info.processName);
11358                if (!app.isolated) {
11359                    // XXX We don't have a way to mark isolated processes
11360                    // as bad, since they don't have a peristent identity.
11361                    mBadProcesses.put(app.info.processName, app.uid,
11362                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11363                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11364                }
11365                app.bad = true;
11366                app.removed = true;
11367                // Don't let services in this process be restarted and potentially
11368                // annoy the user repeatedly.  Unless it is persistent, since those
11369                // processes run critical code.
11370                removeProcessLocked(app, false, false, "crash");
11371                mStackSupervisor.resumeTopActivitiesLocked();
11372                return false;
11373            }
11374            mStackSupervisor.resumeTopActivitiesLocked();
11375        } else {
11376            mStackSupervisor.finishTopRunningActivityLocked(app);
11377        }
11378
11379        // Bump up the crash count of any services currently running in the proc.
11380        for (int i=app.services.size()-1; i>=0; i--) {
11381            // Any services running in the application need to be placed
11382            // back in the pending list.
11383            ServiceRecord sr = app.services.valueAt(i);
11384            sr.crashCount++;
11385        }
11386
11387        // If the crashing process is what we consider to be the "home process" and it has been
11388        // replaced by a third-party app, clear the package preferred activities from packages
11389        // with a home activity running in the process to prevent a repeatedly crashing app
11390        // from blocking the user to manually clear the list.
11391        final ArrayList<ActivityRecord> activities = app.activities;
11392        if (app == mHomeProcess && activities.size() > 0
11393                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11394            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11395                final ActivityRecord r = activities.get(activityNdx);
11396                if (r.isHomeActivity()) {
11397                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11398                    try {
11399                        ActivityThread.getPackageManager()
11400                                .clearPackagePreferredActivities(r.packageName);
11401                    } catch (RemoteException c) {
11402                        // pm is in same process, this will never happen.
11403                    }
11404                }
11405            }
11406        }
11407
11408        if (!app.isolated) {
11409            // XXX Can't keep track of crash times for isolated processes,
11410            // because they don't have a perisistent identity.
11411            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11412        }
11413
11414        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11415        return true;
11416    }
11417
11418    void startAppProblemLocked(ProcessRecord app) {
11419        // If this app is not running under the current user, then we
11420        // can't give it a report button because that would require
11421        // launching the report UI under a different user.
11422        app.errorReportReceiver = null;
11423
11424        for (int userId : mCurrentProfileIds) {
11425            if (app.userId == userId) {
11426                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11427                        mContext, app.info.packageName, app.info.flags);
11428            }
11429        }
11430        skipCurrentReceiverLocked(app);
11431    }
11432
11433    void skipCurrentReceiverLocked(ProcessRecord app) {
11434        for (BroadcastQueue queue : mBroadcastQueues) {
11435            queue.skipCurrentReceiverLocked(app);
11436        }
11437    }
11438
11439    /**
11440     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11441     * The application process will exit immediately after this call returns.
11442     * @param app object of the crashing app, null for the system server
11443     * @param crashInfo describing the exception
11444     */
11445    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11446        ProcessRecord r = findAppProcess(app, "Crash");
11447        final String processName = app == null ? "system_server"
11448                : (r == null ? "unknown" : r.processName);
11449
11450        handleApplicationCrashInner("crash", r, processName, crashInfo);
11451    }
11452
11453    /* Native crash reporting uses this inner version because it needs to be somewhat
11454     * decoupled from the AM-managed cleanup lifecycle
11455     */
11456    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11457            ApplicationErrorReport.CrashInfo crashInfo) {
11458        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11459                UserHandle.getUserId(Binder.getCallingUid()), processName,
11460                r == null ? -1 : r.info.flags,
11461                crashInfo.exceptionClassName,
11462                crashInfo.exceptionMessage,
11463                crashInfo.throwFileName,
11464                crashInfo.throwLineNumber);
11465
11466        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11467
11468        crashApplication(r, crashInfo);
11469    }
11470
11471    public void handleApplicationStrictModeViolation(
11472            IBinder app,
11473            int violationMask,
11474            StrictMode.ViolationInfo info) {
11475        ProcessRecord r = findAppProcess(app, "StrictMode");
11476        if (r == null) {
11477            return;
11478        }
11479
11480        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11481            Integer stackFingerprint = info.hashCode();
11482            boolean logIt = true;
11483            synchronized (mAlreadyLoggedViolatedStacks) {
11484                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11485                    logIt = false;
11486                    // TODO: sub-sample into EventLog for these, with
11487                    // the info.durationMillis?  Then we'd get
11488                    // the relative pain numbers, without logging all
11489                    // the stack traces repeatedly.  We'd want to do
11490                    // likewise in the client code, which also does
11491                    // dup suppression, before the Binder call.
11492                } else {
11493                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11494                        mAlreadyLoggedViolatedStacks.clear();
11495                    }
11496                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11497                }
11498            }
11499            if (logIt) {
11500                logStrictModeViolationToDropBox(r, info);
11501            }
11502        }
11503
11504        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11505            AppErrorResult result = new AppErrorResult();
11506            synchronized (this) {
11507                final long origId = Binder.clearCallingIdentity();
11508
11509                Message msg = Message.obtain();
11510                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11511                HashMap<String, Object> data = new HashMap<String, Object>();
11512                data.put("result", result);
11513                data.put("app", r);
11514                data.put("violationMask", violationMask);
11515                data.put("info", info);
11516                msg.obj = data;
11517                mHandler.sendMessage(msg);
11518
11519                Binder.restoreCallingIdentity(origId);
11520            }
11521            int res = result.get();
11522            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11523        }
11524    }
11525
11526    // Depending on the policy in effect, there could be a bunch of
11527    // these in quick succession so we try to batch these together to
11528    // minimize disk writes, number of dropbox entries, and maximize
11529    // compression, by having more fewer, larger records.
11530    private void logStrictModeViolationToDropBox(
11531            ProcessRecord process,
11532            StrictMode.ViolationInfo info) {
11533        if (info == null) {
11534            return;
11535        }
11536        final boolean isSystemApp = process == null ||
11537                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11538                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11539        final String processName = process == null ? "unknown" : process.processName;
11540        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11541        final DropBoxManager dbox = (DropBoxManager)
11542                mContext.getSystemService(Context.DROPBOX_SERVICE);
11543
11544        // Exit early if the dropbox isn't configured to accept this report type.
11545        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11546
11547        boolean bufferWasEmpty;
11548        boolean needsFlush;
11549        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11550        synchronized (sb) {
11551            bufferWasEmpty = sb.length() == 0;
11552            appendDropBoxProcessHeaders(process, processName, sb);
11553            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11554            sb.append("System-App: ").append(isSystemApp).append("\n");
11555            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11556            if (info.violationNumThisLoop != 0) {
11557                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11558            }
11559            if (info.numAnimationsRunning != 0) {
11560                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11561            }
11562            if (info.broadcastIntentAction != null) {
11563                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11564            }
11565            if (info.durationMillis != -1) {
11566                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11567            }
11568            if (info.numInstances != -1) {
11569                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11570            }
11571            if (info.tags != null) {
11572                for (String tag : info.tags) {
11573                    sb.append("Span-Tag: ").append(tag).append("\n");
11574                }
11575            }
11576            sb.append("\n");
11577            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11578                sb.append(info.crashInfo.stackTrace);
11579            }
11580            sb.append("\n");
11581
11582            // Only buffer up to ~64k.  Various logging bits truncate
11583            // things at 128k.
11584            needsFlush = (sb.length() > 64 * 1024);
11585        }
11586
11587        // Flush immediately if the buffer's grown too large, or this
11588        // is a non-system app.  Non-system apps are isolated with a
11589        // different tag & policy and not batched.
11590        //
11591        // Batching is useful during internal testing with
11592        // StrictMode settings turned up high.  Without batching,
11593        // thousands of separate files could be created on boot.
11594        if (!isSystemApp || needsFlush) {
11595            new Thread("Error dump: " + dropboxTag) {
11596                @Override
11597                public void run() {
11598                    String report;
11599                    synchronized (sb) {
11600                        report = sb.toString();
11601                        sb.delete(0, sb.length());
11602                        sb.trimToSize();
11603                    }
11604                    if (report.length() != 0) {
11605                        dbox.addText(dropboxTag, report);
11606                    }
11607                }
11608            }.start();
11609            return;
11610        }
11611
11612        // System app batching:
11613        if (!bufferWasEmpty) {
11614            // An existing dropbox-writing thread is outstanding, so
11615            // we don't need to start it up.  The existing thread will
11616            // catch the buffer appends we just did.
11617            return;
11618        }
11619
11620        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11621        // (After this point, we shouldn't access AMS internal data structures.)
11622        new Thread("Error dump: " + dropboxTag) {
11623            @Override
11624            public void run() {
11625                // 5 second sleep to let stacks arrive and be batched together
11626                try {
11627                    Thread.sleep(5000);  // 5 seconds
11628                } catch (InterruptedException e) {}
11629
11630                String errorReport;
11631                synchronized (mStrictModeBuffer) {
11632                    errorReport = mStrictModeBuffer.toString();
11633                    if (errorReport.length() == 0) {
11634                        return;
11635                    }
11636                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11637                    mStrictModeBuffer.trimToSize();
11638                }
11639                dbox.addText(dropboxTag, errorReport);
11640            }
11641        }.start();
11642    }
11643
11644    /**
11645     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11646     * @param app object of the crashing app, null for the system server
11647     * @param tag reported by the caller
11648     * @param system whether this wtf is coming from the system
11649     * @param crashInfo describing the context of the error
11650     * @return true if the process should exit immediately (WTF is fatal)
11651     */
11652    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11653            final ApplicationErrorReport.CrashInfo crashInfo) {
11654        final ProcessRecord r = findAppProcess(app, "WTF");
11655        final String processName = app == null ? "system_server"
11656                : (r == null ? "unknown" : r.processName);
11657
11658        EventLog.writeEvent(EventLogTags.AM_WTF,
11659                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11660                processName,
11661                r == null ? -1 : r.info.flags,
11662                tag, crashInfo.exceptionMessage);
11663
11664        if (system) {
11665            // If this is coming from the system, we could very well have low-level
11666            // system locks held, so we want to do this all asynchronously.  And we
11667            // never want this to become fatal, so there is that too.
11668            mHandler.post(new Runnable() {
11669                @Override public void run() {
11670                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11671                            crashInfo);
11672                }
11673            });
11674            return false;
11675        }
11676
11677        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11678
11679        if (r != null && r.pid != Process.myPid() &&
11680                Settings.Global.getInt(mContext.getContentResolver(),
11681                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11682            crashApplication(r, crashInfo);
11683            return true;
11684        } else {
11685            return false;
11686        }
11687    }
11688
11689    /**
11690     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11691     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11692     */
11693    private ProcessRecord findAppProcess(IBinder app, String reason) {
11694        if (app == null) {
11695            return null;
11696        }
11697
11698        synchronized (this) {
11699            final int NP = mProcessNames.getMap().size();
11700            for (int ip=0; ip<NP; ip++) {
11701                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11702                final int NA = apps.size();
11703                for (int ia=0; ia<NA; ia++) {
11704                    ProcessRecord p = apps.valueAt(ia);
11705                    if (p.thread != null && p.thread.asBinder() == app) {
11706                        return p;
11707                    }
11708                }
11709            }
11710
11711            Slog.w(TAG, "Can't find mystery application for " + reason
11712                    + " from pid=" + Binder.getCallingPid()
11713                    + " uid=" + Binder.getCallingUid() + ": " + app);
11714            return null;
11715        }
11716    }
11717
11718    /**
11719     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11720     * to append various headers to the dropbox log text.
11721     */
11722    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11723            StringBuilder sb) {
11724        // Watchdog thread ends up invoking this function (with
11725        // a null ProcessRecord) to add the stack file to dropbox.
11726        // Do not acquire a lock on this (am) in such cases, as it
11727        // could cause a potential deadlock, if and when watchdog
11728        // is invoked due to unavailability of lock on am and it
11729        // would prevent watchdog from killing system_server.
11730        if (process == null) {
11731            sb.append("Process: ").append(processName).append("\n");
11732            return;
11733        }
11734        // Note: ProcessRecord 'process' is guarded by the service
11735        // instance.  (notably process.pkgList, which could otherwise change
11736        // concurrently during execution of this method)
11737        synchronized (this) {
11738            sb.append("Process: ").append(processName).append("\n");
11739            int flags = process.info.flags;
11740            IPackageManager pm = AppGlobals.getPackageManager();
11741            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11742            for (int ip=0; ip<process.pkgList.size(); ip++) {
11743                String pkg = process.pkgList.keyAt(ip);
11744                sb.append("Package: ").append(pkg);
11745                try {
11746                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11747                    if (pi != null) {
11748                        sb.append(" v").append(pi.versionCode);
11749                        if (pi.versionName != null) {
11750                            sb.append(" (").append(pi.versionName).append(")");
11751                        }
11752                    }
11753                } catch (RemoteException e) {
11754                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11755                }
11756                sb.append("\n");
11757            }
11758        }
11759    }
11760
11761    private static String processClass(ProcessRecord process) {
11762        if (process == null || process.pid == MY_PID) {
11763            return "system_server";
11764        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11765            return "system_app";
11766        } else {
11767            return "data_app";
11768        }
11769    }
11770
11771    /**
11772     * Write a description of an error (crash, WTF, ANR) to the drop box.
11773     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11774     * @param process which caused the error, null means the system server
11775     * @param activity which triggered the error, null if unknown
11776     * @param parent activity related to the error, null if unknown
11777     * @param subject line related to the error, null if absent
11778     * @param report in long form describing the error, null if absent
11779     * @param logFile to include in the report, null if none
11780     * @param crashInfo giving an application stack trace, null if absent
11781     */
11782    public void addErrorToDropBox(String eventType,
11783            ProcessRecord process, String processName, ActivityRecord activity,
11784            ActivityRecord parent, String subject,
11785            final String report, final File logFile,
11786            final ApplicationErrorReport.CrashInfo crashInfo) {
11787        // NOTE -- this must never acquire the ActivityManagerService lock,
11788        // otherwise the watchdog may be prevented from resetting the system.
11789
11790        final String dropboxTag = processClass(process) + "_" + eventType;
11791        final DropBoxManager dbox = (DropBoxManager)
11792                mContext.getSystemService(Context.DROPBOX_SERVICE);
11793
11794        // Exit early if the dropbox isn't configured to accept this report type.
11795        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11796
11797        final StringBuilder sb = new StringBuilder(1024);
11798        appendDropBoxProcessHeaders(process, processName, sb);
11799        if (activity != null) {
11800            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11801        }
11802        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11803            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11804        }
11805        if (parent != null && parent != activity) {
11806            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11807        }
11808        if (subject != null) {
11809            sb.append("Subject: ").append(subject).append("\n");
11810        }
11811        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11812        if (Debug.isDebuggerConnected()) {
11813            sb.append("Debugger: Connected\n");
11814        }
11815        sb.append("\n");
11816
11817        // Do the rest in a worker thread to avoid blocking the caller on I/O
11818        // (After this point, we shouldn't access AMS internal data structures.)
11819        Thread worker = new Thread("Error dump: " + dropboxTag) {
11820            @Override
11821            public void run() {
11822                if (report != null) {
11823                    sb.append(report);
11824                }
11825                if (logFile != null) {
11826                    try {
11827                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11828                                    "\n\n[[TRUNCATED]]"));
11829                    } catch (IOException e) {
11830                        Slog.e(TAG, "Error reading " + logFile, e);
11831                    }
11832                }
11833                if (crashInfo != null && crashInfo.stackTrace != null) {
11834                    sb.append(crashInfo.stackTrace);
11835                }
11836
11837                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11838                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11839                if (lines > 0) {
11840                    sb.append("\n");
11841
11842                    // Merge several logcat streams, and take the last N lines
11843                    InputStreamReader input = null;
11844                    try {
11845                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11846                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11847                                "-b", "crash",
11848                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11849
11850                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11851                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11852                        input = new InputStreamReader(logcat.getInputStream());
11853
11854                        int num;
11855                        char[] buf = new char[8192];
11856                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11857                    } catch (IOException e) {
11858                        Slog.e(TAG, "Error running logcat", e);
11859                    } finally {
11860                        if (input != null) try { input.close(); } catch (IOException e) {}
11861                    }
11862                }
11863
11864                dbox.addText(dropboxTag, sb.toString());
11865            }
11866        };
11867
11868        if (process == null) {
11869            // If process is null, we are being called from some internal code
11870            // and may be about to die -- run this synchronously.
11871            worker.run();
11872        } else {
11873            worker.start();
11874        }
11875    }
11876
11877    /**
11878     * Bring up the "unexpected error" dialog box for a crashing app.
11879     * Deal with edge cases (intercepts from instrumented applications,
11880     * ActivityController, error intent receivers, that sort of thing).
11881     * @param r the application crashing
11882     * @param crashInfo describing the failure
11883     */
11884    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11885        long timeMillis = System.currentTimeMillis();
11886        String shortMsg = crashInfo.exceptionClassName;
11887        String longMsg = crashInfo.exceptionMessage;
11888        String stackTrace = crashInfo.stackTrace;
11889        if (shortMsg != null && longMsg != null) {
11890            longMsg = shortMsg + ": " + longMsg;
11891        } else if (shortMsg != null) {
11892            longMsg = shortMsg;
11893        }
11894
11895        AppErrorResult result = new AppErrorResult();
11896        synchronized (this) {
11897            if (mController != null) {
11898                try {
11899                    String name = r != null ? r.processName : null;
11900                    int pid = r != null ? r.pid : Binder.getCallingPid();
11901                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11902                    if (!mController.appCrashed(name, pid,
11903                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11904                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11905                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11906                            Slog.w(TAG, "Skip killing native crashed app " + name
11907                                    + "(" + pid + ") during testing");
11908                        } else {
11909                            Slog.w(TAG, "Force-killing crashed app " + name
11910                                    + " at watcher's request");
11911                            if (r != null) {
11912                                r.kill("crash", true);
11913                            } else {
11914                                // Huh.
11915                                Process.killProcess(pid);
11916                                Process.killProcessGroup(uid, pid);
11917                            }
11918                        }
11919                        return;
11920                    }
11921                } catch (RemoteException e) {
11922                    mController = null;
11923                    Watchdog.getInstance().setActivityController(null);
11924                }
11925            }
11926
11927            final long origId = Binder.clearCallingIdentity();
11928
11929            // If this process is running instrumentation, finish it.
11930            if (r != null && r.instrumentationClass != null) {
11931                Slog.w(TAG, "Error in app " + r.processName
11932                      + " running instrumentation " + r.instrumentationClass + ":");
11933                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11934                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11935                Bundle info = new Bundle();
11936                info.putString("shortMsg", shortMsg);
11937                info.putString("longMsg", longMsg);
11938                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11939                Binder.restoreCallingIdentity(origId);
11940                return;
11941            }
11942
11943            // If we can't identify the process or it's already exceeded its crash quota,
11944            // quit right away without showing a crash dialog.
11945            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11946                Binder.restoreCallingIdentity(origId);
11947                return;
11948            }
11949
11950            Message msg = Message.obtain();
11951            msg.what = SHOW_ERROR_MSG;
11952            HashMap data = new HashMap();
11953            data.put("result", result);
11954            data.put("app", r);
11955            msg.obj = data;
11956            mHandler.sendMessage(msg);
11957
11958            Binder.restoreCallingIdentity(origId);
11959        }
11960
11961        int res = result.get();
11962
11963        Intent appErrorIntent = null;
11964        synchronized (this) {
11965            if (r != null && !r.isolated) {
11966                // XXX Can't keep track of crash time for isolated processes,
11967                // since they don't have a persistent identity.
11968                mProcessCrashTimes.put(r.info.processName, r.uid,
11969                        SystemClock.uptimeMillis());
11970            }
11971            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11972                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11973            }
11974        }
11975
11976        if (appErrorIntent != null) {
11977            try {
11978                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11979            } catch (ActivityNotFoundException e) {
11980                Slog.w(TAG, "bug report receiver dissappeared", e);
11981            }
11982        }
11983    }
11984
11985    Intent createAppErrorIntentLocked(ProcessRecord r,
11986            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11987        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11988        if (report == null) {
11989            return null;
11990        }
11991        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11992        result.setComponent(r.errorReportReceiver);
11993        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11994        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11995        return result;
11996    }
11997
11998    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11999            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12000        if (r.errorReportReceiver == null) {
12001            return null;
12002        }
12003
12004        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12005            return null;
12006        }
12007
12008        ApplicationErrorReport report = new ApplicationErrorReport();
12009        report.packageName = r.info.packageName;
12010        report.installerPackageName = r.errorReportReceiver.getPackageName();
12011        report.processName = r.processName;
12012        report.time = timeMillis;
12013        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12014
12015        if (r.crashing || r.forceCrashReport) {
12016            report.type = ApplicationErrorReport.TYPE_CRASH;
12017            report.crashInfo = crashInfo;
12018        } else if (r.notResponding) {
12019            report.type = ApplicationErrorReport.TYPE_ANR;
12020            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12021
12022            report.anrInfo.activity = r.notRespondingReport.tag;
12023            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12024            report.anrInfo.info = r.notRespondingReport.longMsg;
12025        }
12026
12027        return report;
12028    }
12029
12030    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12031        enforceNotIsolatedCaller("getProcessesInErrorState");
12032        // assume our apps are happy - lazy create the list
12033        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12034
12035        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12036                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12037        int userId = UserHandle.getUserId(Binder.getCallingUid());
12038
12039        synchronized (this) {
12040
12041            // iterate across all processes
12042            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12043                ProcessRecord app = mLruProcesses.get(i);
12044                if (!allUsers && app.userId != userId) {
12045                    continue;
12046                }
12047                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12048                    // This one's in trouble, so we'll generate a report for it
12049                    // crashes are higher priority (in case there's a crash *and* an anr)
12050                    ActivityManager.ProcessErrorStateInfo report = null;
12051                    if (app.crashing) {
12052                        report = app.crashingReport;
12053                    } else if (app.notResponding) {
12054                        report = app.notRespondingReport;
12055                    }
12056
12057                    if (report != null) {
12058                        if (errList == null) {
12059                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12060                        }
12061                        errList.add(report);
12062                    } else {
12063                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12064                                " crashing = " + app.crashing +
12065                                " notResponding = " + app.notResponding);
12066                    }
12067                }
12068            }
12069        }
12070
12071        return errList;
12072    }
12073
12074    static int procStateToImportance(int procState, int memAdj,
12075            ActivityManager.RunningAppProcessInfo currApp) {
12076        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12077        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12078            currApp.lru = memAdj;
12079        } else {
12080            currApp.lru = 0;
12081        }
12082        return imp;
12083    }
12084
12085    private void fillInProcMemInfo(ProcessRecord app,
12086            ActivityManager.RunningAppProcessInfo outInfo) {
12087        outInfo.pid = app.pid;
12088        outInfo.uid = app.info.uid;
12089        if (mHeavyWeightProcess == app) {
12090            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12091        }
12092        if (app.persistent) {
12093            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12094        }
12095        if (app.activities.size() > 0) {
12096            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12097        }
12098        outInfo.lastTrimLevel = app.trimMemoryLevel;
12099        int adj = app.curAdj;
12100        int procState = app.curProcState;
12101        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12102        outInfo.importanceReasonCode = app.adjTypeCode;
12103        outInfo.processState = app.curProcState;
12104    }
12105
12106    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12107        enforceNotIsolatedCaller("getRunningAppProcesses");
12108        // Lazy instantiation of list
12109        List<ActivityManager.RunningAppProcessInfo> runList = null;
12110        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12111                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12112        int userId = UserHandle.getUserId(Binder.getCallingUid());
12113        synchronized (this) {
12114            // Iterate across all processes
12115            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12116                ProcessRecord app = mLruProcesses.get(i);
12117                if (!allUsers && app.userId != userId) {
12118                    continue;
12119                }
12120                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12121                    // Generate process state info for running application
12122                    ActivityManager.RunningAppProcessInfo currApp =
12123                        new ActivityManager.RunningAppProcessInfo(app.processName,
12124                                app.pid, app.getPackageList());
12125                    fillInProcMemInfo(app, currApp);
12126                    if (app.adjSource instanceof ProcessRecord) {
12127                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12128                        currApp.importanceReasonImportance =
12129                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12130                                        app.adjSourceProcState);
12131                    } else if (app.adjSource instanceof ActivityRecord) {
12132                        ActivityRecord r = (ActivityRecord)app.adjSource;
12133                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12134                    }
12135                    if (app.adjTarget instanceof ComponentName) {
12136                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12137                    }
12138                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12139                    //        + " lru=" + currApp.lru);
12140                    if (runList == null) {
12141                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12142                    }
12143                    runList.add(currApp);
12144                }
12145            }
12146        }
12147        return runList;
12148    }
12149
12150    public List<ApplicationInfo> getRunningExternalApplications() {
12151        enforceNotIsolatedCaller("getRunningExternalApplications");
12152        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12153        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12154        if (runningApps != null && runningApps.size() > 0) {
12155            Set<String> extList = new HashSet<String>();
12156            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12157                if (app.pkgList != null) {
12158                    for (String pkg : app.pkgList) {
12159                        extList.add(pkg);
12160                    }
12161                }
12162            }
12163            IPackageManager pm = AppGlobals.getPackageManager();
12164            for (String pkg : extList) {
12165                try {
12166                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12167                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12168                        retList.add(info);
12169                    }
12170                } catch (RemoteException e) {
12171                }
12172            }
12173        }
12174        return retList;
12175    }
12176
12177    @Override
12178    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12179        enforceNotIsolatedCaller("getMyMemoryState");
12180        synchronized (this) {
12181            ProcessRecord proc;
12182            synchronized (mPidsSelfLocked) {
12183                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12184            }
12185            fillInProcMemInfo(proc, outInfo);
12186        }
12187    }
12188
12189    @Override
12190    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12191        if (checkCallingPermission(android.Manifest.permission.DUMP)
12192                != PackageManager.PERMISSION_GRANTED) {
12193            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12194                    + Binder.getCallingPid()
12195                    + ", uid=" + Binder.getCallingUid()
12196                    + " without permission "
12197                    + android.Manifest.permission.DUMP);
12198            return;
12199        }
12200
12201        boolean dumpAll = false;
12202        boolean dumpClient = false;
12203        String dumpPackage = null;
12204
12205        int opti = 0;
12206        while (opti < args.length) {
12207            String opt = args[opti];
12208            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12209                break;
12210            }
12211            opti++;
12212            if ("-a".equals(opt)) {
12213                dumpAll = true;
12214            } else if ("-c".equals(opt)) {
12215                dumpClient = true;
12216            } else if ("-h".equals(opt)) {
12217                pw.println("Activity manager dump options:");
12218                pw.println("  [-a] [-c] [-h] [cmd] ...");
12219                pw.println("  cmd may be one of:");
12220                pw.println("    a[ctivities]: activity stack state");
12221                pw.println("    r[recents]: recent activities state");
12222                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12223                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12224                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12225                pw.println("    o[om]: out of memory management");
12226                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12227                pw.println("    provider [COMP_SPEC]: provider client-side state");
12228                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12229                pw.println("    service [COMP_SPEC]: service client-side state");
12230                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12231                pw.println("    all: dump all activities");
12232                pw.println("    top: dump the top activity");
12233                pw.println("    write: write all pending state to storage");
12234                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12235                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12236                pw.println("    a partial substring in a component name, a");
12237                pw.println("    hex object identifier.");
12238                pw.println("  -a: include all available server state.");
12239                pw.println("  -c: include client state.");
12240                return;
12241            } else {
12242                pw.println("Unknown argument: " + opt + "; use -h for help");
12243            }
12244        }
12245
12246        long origId = Binder.clearCallingIdentity();
12247        boolean more = false;
12248        // Is the caller requesting to dump a particular piece of data?
12249        if (opti < args.length) {
12250            String cmd = args[opti];
12251            opti++;
12252            if ("activities".equals(cmd) || "a".equals(cmd)) {
12253                synchronized (this) {
12254                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12255                }
12256            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12257                synchronized (this) {
12258                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12259                }
12260            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12261                String[] newArgs;
12262                String name;
12263                if (opti >= args.length) {
12264                    name = null;
12265                    newArgs = EMPTY_STRING_ARRAY;
12266                } else {
12267                    name = args[opti];
12268                    opti++;
12269                    newArgs = new String[args.length - opti];
12270                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12271                            args.length - opti);
12272                }
12273                synchronized (this) {
12274                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12275                }
12276            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12277                String[] newArgs;
12278                String name;
12279                if (opti >= args.length) {
12280                    name = null;
12281                    newArgs = EMPTY_STRING_ARRAY;
12282                } else {
12283                    name = args[opti];
12284                    opti++;
12285                    newArgs = new String[args.length - opti];
12286                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12287                            args.length - opti);
12288                }
12289                synchronized (this) {
12290                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12291                }
12292            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12293                String[] newArgs;
12294                String name;
12295                if (opti >= args.length) {
12296                    name = null;
12297                    newArgs = EMPTY_STRING_ARRAY;
12298                } else {
12299                    name = args[opti];
12300                    opti++;
12301                    newArgs = new String[args.length - opti];
12302                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12303                            args.length - opti);
12304                }
12305                synchronized (this) {
12306                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12307                }
12308            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12309                synchronized (this) {
12310                    dumpOomLocked(fd, pw, args, opti, true);
12311                }
12312            } else if ("provider".equals(cmd)) {
12313                String[] newArgs;
12314                String name;
12315                if (opti >= args.length) {
12316                    name = null;
12317                    newArgs = EMPTY_STRING_ARRAY;
12318                } else {
12319                    name = args[opti];
12320                    opti++;
12321                    newArgs = new String[args.length - opti];
12322                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12323                }
12324                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12325                    pw.println("No providers match: " + name);
12326                    pw.println("Use -h for help.");
12327                }
12328            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12329                synchronized (this) {
12330                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12331                }
12332            } else if ("service".equals(cmd)) {
12333                String[] newArgs;
12334                String name;
12335                if (opti >= args.length) {
12336                    name = null;
12337                    newArgs = EMPTY_STRING_ARRAY;
12338                } else {
12339                    name = args[opti];
12340                    opti++;
12341                    newArgs = new String[args.length - opti];
12342                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12343                            args.length - opti);
12344                }
12345                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12346                    pw.println("No services match: " + name);
12347                    pw.println("Use -h for help.");
12348                }
12349            } else if ("package".equals(cmd)) {
12350                String[] newArgs;
12351                if (opti >= args.length) {
12352                    pw.println("package: no package name specified");
12353                    pw.println("Use -h for help.");
12354                } else {
12355                    dumpPackage = args[opti];
12356                    opti++;
12357                    newArgs = new String[args.length - opti];
12358                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12359                            args.length - opti);
12360                    args = newArgs;
12361                    opti = 0;
12362                    more = true;
12363                }
12364            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12365                synchronized (this) {
12366                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12367                }
12368            } else if ("write".equals(cmd)) {
12369                mTaskPersister.flush();
12370                pw.println("All tasks persisted.");
12371                return;
12372            } else {
12373                // Dumping a single activity?
12374                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12375                    pw.println("Bad activity command, or no activities match: " + cmd);
12376                    pw.println("Use -h for help.");
12377                }
12378            }
12379            if (!more) {
12380                Binder.restoreCallingIdentity(origId);
12381                return;
12382            }
12383        }
12384
12385        // No piece of data specified, dump everything.
12386        synchronized (this) {
12387            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12388            pw.println();
12389            if (dumpAll) {
12390                pw.println("-------------------------------------------------------------------------------");
12391            }
12392            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12393            pw.println();
12394            if (dumpAll) {
12395                pw.println("-------------------------------------------------------------------------------");
12396            }
12397            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12398            pw.println();
12399            if (dumpAll) {
12400                pw.println("-------------------------------------------------------------------------------");
12401            }
12402            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12403            pw.println();
12404            if (dumpAll) {
12405                pw.println("-------------------------------------------------------------------------------");
12406            }
12407            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12408            pw.println();
12409            if (dumpAll) {
12410                pw.println("-------------------------------------------------------------------------------");
12411            }
12412            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12413            pw.println();
12414            if (dumpAll) {
12415                pw.println("-------------------------------------------------------------------------------");
12416            }
12417            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12418        }
12419        Binder.restoreCallingIdentity(origId);
12420    }
12421
12422    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12423            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12424        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12425
12426        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12427                dumpPackage);
12428        boolean needSep = printedAnything;
12429
12430        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12431                dumpPackage, needSep, "  mFocusedActivity: ");
12432        if (printed) {
12433            printedAnything = true;
12434            needSep = false;
12435        }
12436
12437        if (dumpPackage == null) {
12438            if (needSep) {
12439                pw.println();
12440            }
12441            needSep = true;
12442            printedAnything = true;
12443            mStackSupervisor.dump(pw, "  ");
12444        }
12445
12446        if (!printedAnything) {
12447            pw.println("  (nothing)");
12448        }
12449    }
12450
12451    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12452            int opti, boolean dumpAll, String dumpPackage) {
12453        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12454
12455        boolean printedAnything = false;
12456
12457        if (mRecentTasks.size() > 0) {
12458            boolean printedHeader = false;
12459
12460            final int N = mRecentTasks.size();
12461            for (int i=0; i<N; i++) {
12462                TaskRecord tr = mRecentTasks.get(i);
12463                if (dumpPackage != null) {
12464                    if (tr.realActivity == null ||
12465                            !dumpPackage.equals(tr.realActivity)) {
12466                        continue;
12467                    }
12468                }
12469                if (!printedHeader) {
12470                    pw.println("  Recent tasks:");
12471                    printedHeader = true;
12472                    printedAnything = true;
12473                }
12474                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12475                        pw.println(tr);
12476                if (dumpAll) {
12477                    mRecentTasks.get(i).dump(pw, "    ");
12478                }
12479            }
12480        }
12481
12482        if (!printedAnything) {
12483            pw.println("  (nothing)");
12484        }
12485    }
12486
12487    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12488            int opti, boolean dumpAll, String dumpPackage) {
12489        boolean needSep = false;
12490        boolean printedAnything = false;
12491        int numPers = 0;
12492
12493        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12494
12495        if (dumpAll) {
12496            final int NP = mProcessNames.getMap().size();
12497            for (int ip=0; ip<NP; ip++) {
12498                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12499                final int NA = procs.size();
12500                for (int ia=0; ia<NA; ia++) {
12501                    ProcessRecord r = procs.valueAt(ia);
12502                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12503                        continue;
12504                    }
12505                    if (!needSep) {
12506                        pw.println("  All known processes:");
12507                        needSep = true;
12508                        printedAnything = true;
12509                    }
12510                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12511                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12512                        pw.print(" "); pw.println(r);
12513                    r.dump(pw, "    ");
12514                    if (r.persistent) {
12515                        numPers++;
12516                    }
12517                }
12518            }
12519        }
12520
12521        if (mIsolatedProcesses.size() > 0) {
12522            boolean printed = false;
12523            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12524                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12525                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12526                    continue;
12527                }
12528                if (!printed) {
12529                    if (needSep) {
12530                        pw.println();
12531                    }
12532                    pw.println("  Isolated process list (sorted by uid):");
12533                    printedAnything = true;
12534                    printed = true;
12535                    needSep = true;
12536                }
12537                pw.println(String.format("%sIsolated #%2d: %s",
12538                        "    ", i, r.toString()));
12539            }
12540        }
12541
12542        if (mLruProcesses.size() > 0) {
12543            if (needSep) {
12544                pw.println();
12545            }
12546            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12547                    pw.print(" total, non-act at ");
12548                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12549                    pw.print(", non-svc at ");
12550                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12551                    pw.println("):");
12552            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12553            needSep = true;
12554            printedAnything = true;
12555        }
12556
12557        if (dumpAll || dumpPackage != null) {
12558            synchronized (mPidsSelfLocked) {
12559                boolean printed = false;
12560                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12561                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12562                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12563                        continue;
12564                    }
12565                    if (!printed) {
12566                        if (needSep) pw.println();
12567                        needSep = true;
12568                        pw.println("  PID mappings:");
12569                        printed = true;
12570                        printedAnything = true;
12571                    }
12572                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12573                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12574                }
12575            }
12576        }
12577
12578        if (mForegroundProcesses.size() > 0) {
12579            synchronized (mPidsSelfLocked) {
12580                boolean printed = false;
12581                for (int i=0; i<mForegroundProcesses.size(); i++) {
12582                    ProcessRecord r = mPidsSelfLocked.get(
12583                            mForegroundProcesses.valueAt(i).pid);
12584                    if (dumpPackage != null && (r == null
12585                            || !r.pkgList.containsKey(dumpPackage))) {
12586                        continue;
12587                    }
12588                    if (!printed) {
12589                        if (needSep) pw.println();
12590                        needSep = true;
12591                        pw.println("  Foreground Processes:");
12592                        printed = true;
12593                        printedAnything = true;
12594                    }
12595                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12596                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12597                }
12598            }
12599        }
12600
12601        if (mPersistentStartingProcesses.size() > 0) {
12602            if (needSep) pw.println();
12603            needSep = true;
12604            printedAnything = true;
12605            pw.println("  Persisent processes that are starting:");
12606            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12607                    "Starting Norm", "Restarting PERS", dumpPackage);
12608        }
12609
12610        if (mRemovedProcesses.size() > 0) {
12611            if (needSep) pw.println();
12612            needSep = true;
12613            printedAnything = true;
12614            pw.println("  Processes that are being removed:");
12615            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12616                    "Removed Norm", "Removed PERS", dumpPackage);
12617        }
12618
12619        if (mProcessesOnHold.size() > 0) {
12620            if (needSep) pw.println();
12621            needSep = true;
12622            printedAnything = true;
12623            pw.println("  Processes that are on old until the system is ready:");
12624            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12625                    "OnHold Norm", "OnHold PERS", dumpPackage);
12626        }
12627
12628        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12629
12630        if (mProcessCrashTimes.getMap().size() > 0) {
12631            boolean printed = false;
12632            long now = SystemClock.uptimeMillis();
12633            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12634            final int NP = pmap.size();
12635            for (int ip=0; ip<NP; ip++) {
12636                String pname = pmap.keyAt(ip);
12637                SparseArray<Long> uids = pmap.valueAt(ip);
12638                final int N = uids.size();
12639                for (int i=0; i<N; i++) {
12640                    int puid = uids.keyAt(i);
12641                    ProcessRecord r = mProcessNames.get(pname, puid);
12642                    if (dumpPackage != null && (r == null
12643                            || !r.pkgList.containsKey(dumpPackage))) {
12644                        continue;
12645                    }
12646                    if (!printed) {
12647                        if (needSep) pw.println();
12648                        needSep = true;
12649                        pw.println("  Time since processes crashed:");
12650                        printed = true;
12651                        printedAnything = true;
12652                    }
12653                    pw.print("    Process "); pw.print(pname);
12654                            pw.print(" uid "); pw.print(puid);
12655                            pw.print(": last crashed ");
12656                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12657                            pw.println(" ago");
12658                }
12659            }
12660        }
12661
12662        if (mBadProcesses.getMap().size() > 0) {
12663            boolean printed = false;
12664            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12665            final int NP = pmap.size();
12666            for (int ip=0; ip<NP; ip++) {
12667                String pname = pmap.keyAt(ip);
12668                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12669                final int N = uids.size();
12670                for (int i=0; i<N; i++) {
12671                    int puid = uids.keyAt(i);
12672                    ProcessRecord r = mProcessNames.get(pname, puid);
12673                    if (dumpPackage != null && (r == null
12674                            || !r.pkgList.containsKey(dumpPackage))) {
12675                        continue;
12676                    }
12677                    if (!printed) {
12678                        if (needSep) pw.println();
12679                        needSep = true;
12680                        pw.println("  Bad processes:");
12681                        printedAnything = true;
12682                    }
12683                    BadProcessInfo info = uids.valueAt(i);
12684                    pw.print("    Bad process "); pw.print(pname);
12685                            pw.print(" uid "); pw.print(puid);
12686                            pw.print(": crashed at time "); pw.println(info.time);
12687                    if (info.shortMsg != null) {
12688                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12689                    }
12690                    if (info.longMsg != null) {
12691                        pw.print("      Long msg: "); pw.println(info.longMsg);
12692                    }
12693                    if (info.stack != null) {
12694                        pw.println("      Stack:");
12695                        int lastPos = 0;
12696                        for (int pos=0; pos<info.stack.length(); pos++) {
12697                            if (info.stack.charAt(pos) == '\n') {
12698                                pw.print("        ");
12699                                pw.write(info.stack, lastPos, pos-lastPos);
12700                                pw.println();
12701                                lastPos = pos+1;
12702                            }
12703                        }
12704                        if (lastPos < info.stack.length()) {
12705                            pw.print("        ");
12706                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12707                            pw.println();
12708                        }
12709                    }
12710                }
12711            }
12712        }
12713
12714        if (dumpPackage == null) {
12715            pw.println();
12716            needSep = false;
12717            pw.println("  mStartedUsers:");
12718            for (int i=0; i<mStartedUsers.size(); i++) {
12719                UserStartedState uss = mStartedUsers.valueAt(i);
12720                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12721                        pw.print(": "); uss.dump("", pw);
12722            }
12723            pw.print("  mStartedUserArray: [");
12724            for (int i=0; i<mStartedUserArray.length; i++) {
12725                if (i > 0) pw.print(", ");
12726                pw.print(mStartedUserArray[i]);
12727            }
12728            pw.println("]");
12729            pw.print("  mUserLru: [");
12730            for (int i=0; i<mUserLru.size(); i++) {
12731                if (i > 0) pw.print(", ");
12732                pw.print(mUserLru.get(i));
12733            }
12734            pw.println("]");
12735            if (dumpAll) {
12736                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12737            }
12738            synchronized (mUserProfileGroupIdsSelfLocked) {
12739                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12740                    pw.println("  mUserProfileGroupIds:");
12741                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12742                        pw.print("    User #");
12743                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12744                        pw.print(" -> profile #");
12745                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12746                    }
12747                }
12748            }
12749        }
12750        if (mHomeProcess != null && (dumpPackage == null
12751                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12752            if (needSep) {
12753                pw.println();
12754                needSep = false;
12755            }
12756            pw.println("  mHomeProcess: " + mHomeProcess);
12757        }
12758        if (mPreviousProcess != null && (dumpPackage == null
12759                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12760            if (needSep) {
12761                pw.println();
12762                needSep = false;
12763            }
12764            pw.println("  mPreviousProcess: " + mPreviousProcess);
12765        }
12766        if (dumpAll) {
12767            StringBuilder sb = new StringBuilder(128);
12768            sb.append("  mPreviousProcessVisibleTime: ");
12769            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12770            pw.println(sb);
12771        }
12772        if (mHeavyWeightProcess != null && (dumpPackage == null
12773                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12774            if (needSep) {
12775                pw.println();
12776                needSep = false;
12777            }
12778            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12779        }
12780        if (dumpPackage == null) {
12781            pw.println("  mConfiguration: " + mConfiguration);
12782        }
12783        if (dumpAll) {
12784            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12785            if (mCompatModePackages.getPackages().size() > 0) {
12786                boolean printed = false;
12787                for (Map.Entry<String, Integer> entry
12788                        : mCompatModePackages.getPackages().entrySet()) {
12789                    String pkg = entry.getKey();
12790                    int mode = entry.getValue();
12791                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12792                        continue;
12793                    }
12794                    if (!printed) {
12795                        pw.println("  mScreenCompatPackages:");
12796                        printed = true;
12797                    }
12798                    pw.print("    "); pw.print(pkg); pw.print(": ");
12799                            pw.print(mode); pw.println();
12800                }
12801            }
12802        }
12803        if (dumpPackage == null) {
12804            if (mSleeping || mWentToSleep || mLockScreenShown) {
12805                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12806                        + " mLockScreenShown " + mLockScreenShown);
12807            }
12808            if (mShuttingDown || mRunningVoice) {
12809                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12810            }
12811        }
12812        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12813                || mOrigWaitForDebugger) {
12814            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12815                    || dumpPackage.equals(mOrigDebugApp)) {
12816                if (needSep) {
12817                    pw.println();
12818                    needSep = false;
12819                }
12820                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12821                        + " mDebugTransient=" + mDebugTransient
12822                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12823            }
12824        }
12825        if (mOpenGlTraceApp != null) {
12826            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12827                if (needSep) {
12828                    pw.println();
12829                    needSep = false;
12830                }
12831                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12832            }
12833        }
12834        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12835                || mProfileFd != null) {
12836            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12837                if (needSep) {
12838                    pw.println();
12839                    needSep = false;
12840                }
12841                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12842                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12843                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12844                        + mAutoStopProfiler);
12845                pw.println("  mProfileType=" + mProfileType);
12846            }
12847        }
12848        if (dumpPackage == null) {
12849            if (mAlwaysFinishActivities || mController != null) {
12850                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12851                        + " mController=" + mController);
12852            }
12853            if (dumpAll) {
12854                pw.println("  Total persistent processes: " + numPers);
12855                pw.println("  mProcessesReady=" + mProcessesReady
12856                        + " mSystemReady=" + mSystemReady);
12857                pw.println("  mBooting=" + mBooting
12858                        + " mBooted=" + mBooted
12859                        + " mFactoryTest=" + mFactoryTest);
12860                pw.print("  mLastPowerCheckRealtime=");
12861                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12862                        pw.println("");
12863                pw.print("  mLastPowerCheckUptime=");
12864                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12865                        pw.println("");
12866                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12867                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12868                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12869                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12870                        + " (" + mLruProcesses.size() + " total)"
12871                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12872                        + " mNumServiceProcs=" + mNumServiceProcs
12873                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12874                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12875                        + " mLastMemoryLevel" + mLastMemoryLevel
12876                        + " mLastNumProcesses" + mLastNumProcesses);
12877                long now = SystemClock.uptimeMillis();
12878                pw.print("  mLastIdleTime=");
12879                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12880                        pw.print(" mLowRamSinceLastIdle=");
12881                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12882                        pw.println();
12883            }
12884        }
12885
12886        if (!printedAnything) {
12887            pw.println("  (nothing)");
12888        }
12889    }
12890
12891    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12892            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12893        if (mProcessesToGc.size() > 0) {
12894            boolean printed = false;
12895            long now = SystemClock.uptimeMillis();
12896            for (int i=0; i<mProcessesToGc.size(); i++) {
12897                ProcessRecord proc = mProcessesToGc.get(i);
12898                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12899                    continue;
12900                }
12901                if (!printed) {
12902                    if (needSep) pw.println();
12903                    needSep = true;
12904                    pw.println("  Processes that are waiting to GC:");
12905                    printed = true;
12906                }
12907                pw.print("    Process "); pw.println(proc);
12908                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12909                        pw.print(", last gced=");
12910                        pw.print(now-proc.lastRequestedGc);
12911                        pw.print(" ms ago, last lowMem=");
12912                        pw.print(now-proc.lastLowMemory);
12913                        pw.println(" ms ago");
12914
12915            }
12916        }
12917        return needSep;
12918    }
12919
12920    void printOomLevel(PrintWriter pw, String name, int adj) {
12921        pw.print("    ");
12922        if (adj >= 0) {
12923            pw.print(' ');
12924            if (adj < 10) pw.print(' ');
12925        } else {
12926            if (adj > -10) pw.print(' ');
12927        }
12928        pw.print(adj);
12929        pw.print(": ");
12930        pw.print(name);
12931        pw.print(" (");
12932        pw.print(mProcessList.getMemLevel(adj)/1024);
12933        pw.println(" kB)");
12934    }
12935
12936    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12937            int opti, boolean dumpAll) {
12938        boolean needSep = false;
12939
12940        if (mLruProcesses.size() > 0) {
12941            if (needSep) pw.println();
12942            needSep = true;
12943            pw.println("  OOM levels:");
12944            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12945            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12946            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12947            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12948            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12949            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12950            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12951            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12952            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12953            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12954            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12955            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12956            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12957
12958            if (needSep) pw.println();
12959            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12960                    pw.print(" total, non-act at ");
12961                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12962                    pw.print(", non-svc at ");
12963                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12964                    pw.println("):");
12965            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12966            needSep = true;
12967        }
12968
12969        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12970
12971        pw.println();
12972        pw.println("  mHomeProcess: " + mHomeProcess);
12973        pw.println("  mPreviousProcess: " + mPreviousProcess);
12974        if (mHeavyWeightProcess != null) {
12975            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12976        }
12977
12978        return true;
12979    }
12980
12981    /**
12982     * There are three ways to call this:
12983     *  - no provider specified: dump all the providers
12984     *  - a flattened component name that matched an existing provider was specified as the
12985     *    first arg: dump that one provider
12986     *  - the first arg isn't the flattened component name of an existing provider:
12987     *    dump all providers whose component contains the first arg as a substring
12988     */
12989    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12990            int opti, boolean dumpAll) {
12991        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12992    }
12993
12994    static class ItemMatcher {
12995        ArrayList<ComponentName> components;
12996        ArrayList<String> strings;
12997        ArrayList<Integer> objects;
12998        boolean all;
12999
13000        ItemMatcher() {
13001            all = true;
13002        }
13003
13004        void build(String name) {
13005            ComponentName componentName = ComponentName.unflattenFromString(name);
13006            if (componentName != null) {
13007                if (components == null) {
13008                    components = new ArrayList<ComponentName>();
13009                }
13010                components.add(componentName);
13011                all = false;
13012            } else {
13013                int objectId = 0;
13014                // Not a '/' separated full component name; maybe an object ID?
13015                try {
13016                    objectId = Integer.parseInt(name, 16);
13017                    if (objects == null) {
13018                        objects = new ArrayList<Integer>();
13019                    }
13020                    objects.add(objectId);
13021                    all = false;
13022                } catch (RuntimeException e) {
13023                    // Not an integer; just do string match.
13024                    if (strings == null) {
13025                        strings = new ArrayList<String>();
13026                    }
13027                    strings.add(name);
13028                    all = false;
13029                }
13030            }
13031        }
13032
13033        int build(String[] args, int opti) {
13034            for (; opti<args.length; opti++) {
13035                String name = args[opti];
13036                if ("--".equals(name)) {
13037                    return opti+1;
13038                }
13039                build(name);
13040            }
13041            return opti;
13042        }
13043
13044        boolean match(Object object, ComponentName comp) {
13045            if (all) {
13046                return true;
13047            }
13048            if (components != null) {
13049                for (int i=0; i<components.size(); i++) {
13050                    if (components.get(i).equals(comp)) {
13051                        return true;
13052                    }
13053                }
13054            }
13055            if (objects != null) {
13056                for (int i=0; i<objects.size(); i++) {
13057                    if (System.identityHashCode(object) == objects.get(i)) {
13058                        return true;
13059                    }
13060                }
13061            }
13062            if (strings != null) {
13063                String flat = comp.flattenToString();
13064                for (int i=0; i<strings.size(); i++) {
13065                    if (flat.contains(strings.get(i))) {
13066                        return true;
13067                    }
13068                }
13069            }
13070            return false;
13071        }
13072    }
13073
13074    /**
13075     * There are three things that cmd can be:
13076     *  - a flattened component name that matches an existing activity
13077     *  - the cmd arg isn't the flattened component name of an existing activity:
13078     *    dump all activity whose component contains the cmd as a substring
13079     *  - A hex number of the ActivityRecord object instance.
13080     */
13081    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13082            int opti, boolean dumpAll) {
13083        ArrayList<ActivityRecord> activities;
13084
13085        synchronized (this) {
13086            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13087        }
13088
13089        if (activities.size() <= 0) {
13090            return false;
13091        }
13092
13093        String[] newArgs = new String[args.length - opti];
13094        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13095
13096        TaskRecord lastTask = null;
13097        boolean needSep = false;
13098        for (int i=activities.size()-1; i>=0; i--) {
13099            ActivityRecord r = activities.get(i);
13100            if (needSep) {
13101                pw.println();
13102            }
13103            needSep = true;
13104            synchronized (this) {
13105                if (lastTask != r.task) {
13106                    lastTask = r.task;
13107                    pw.print("TASK "); pw.print(lastTask.affinity);
13108                            pw.print(" id="); pw.println(lastTask.taskId);
13109                    if (dumpAll) {
13110                        lastTask.dump(pw, "  ");
13111                    }
13112                }
13113            }
13114            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13115        }
13116        return true;
13117    }
13118
13119    /**
13120     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13121     * there is a thread associated with the activity.
13122     */
13123    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13124            final ActivityRecord r, String[] args, boolean dumpAll) {
13125        String innerPrefix = prefix + "  ";
13126        synchronized (this) {
13127            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13128                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13129                    pw.print(" pid=");
13130                    if (r.app != null) pw.println(r.app.pid);
13131                    else pw.println("(not running)");
13132            if (dumpAll) {
13133                r.dump(pw, innerPrefix);
13134            }
13135        }
13136        if (r.app != null && r.app.thread != null) {
13137            // flush anything that is already in the PrintWriter since the thread is going
13138            // to write to the file descriptor directly
13139            pw.flush();
13140            try {
13141                TransferPipe tp = new TransferPipe();
13142                try {
13143                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13144                            r.appToken, innerPrefix, args);
13145                    tp.go(fd);
13146                } finally {
13147                    tp.kill();
13148                }
13149            } catch (IOException e) {
13150                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13151            } catch (RemoteException e) {
13152                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13153            }
13154        }
13155    }
13156
13157    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13158            int opti, boolean dumpAll, String dumpPackage) {
13159        boolean needSep = false;
13160        boolean onlyHistory = false;
13161        boolean printedAnything = false;
13162
13163        if ("history".equals(dumpPackage)) {
13164            if (opti < args.length && "-s".equals(args[opti])) {
13165                dumpAll = false;
13166            }
13167            onlyHistory = true;
13168            dumpPackage = null;
13169        }
13170
13171        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13172        if (!onlyHistory && dumpAll) {
13173            if (mRegisteredReceivers.size() > 0) {
13174                boolean printed = false;
13175                Iterator it = mRegisteredReceivers.values().iterator();
13176                while (it.hasNext()) {
13177                    ReceiverList r = (ReceiverList)it.next();
13178                    if (dumpPackage != null && (r.app == null ||
13179                            !dumpPackage.equals(r.app.info.packageName))) {
13180                        continue;
13181                    }
13182                    if (!printed) {
13183                        pw.println("  Registered Receivers:");
13184                        needSep = true;
13185                        printed = true;
13186                        printedAnything = true;
13187                    }
13188                    pw.print("  * "); pw.println(r);
13189                    r.dump(pw, "    ");
13190                }
13191            }
13192
13193            if (mReceiverResolver.dump(pw, needSep ?
13194                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13195                    "    ", dumpPackage, false)) {
13196                needSep = true;
13197                printedAnything = true;
13198            }
13199        }
13200
13201        for (BroadcastQueue q : mBroadcastQueues) {
13202            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13203            printedAnything |= needSep;
13204        }
13205
13206        needSep = true;
13207
13208        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13209            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13210                if (needSep) {
13211                    pw.println();
13212                }
13213                needSep = true;
13214                printedAnything = true;
13215                pw.print("  Sticky broadcasts for user ");
13216                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13217                StringBuilder sb = new StringBuilder(128);
13218                for (Map.Entry<String, ArrayList<Intent>> ent
13219                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13220                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13221                    if (dumpAll) {
13222                        pw.println(":");
13223                        ArrayList<Intent> intents = ent.getValue();
13224                        final int N = intents.size();
13225                        for (int i=0; i<N; i++) {
13226                            sb.setLength(0);
13227                            sb.append("    Intent: ");
13228                            intents.get(i).toShortString(sb, false, true, false, false);
13229                            pw.println(sb.toString());
13230                            Bundle bundle = intents.get(i).getExtras();
13231                            if (bundle != null) {
13232                                pw.print("      ");
13233                                pw.println(bundle.toString());
13234                            }
13235                        }
13236                    } else {
13237                        pw.println("");
13238                    }
13239                }
13240            }
13241        }
13242
13243        if (!onlyHistory && dumpAll) {
13244            pw.println();
13245            for (BroadcastQueue queue : mBroadcastQueues) {
13246                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13247                        + queue.mBroadcastsScheduled);
13248            }
13249            pw.println("  mHandler:");
13250            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13251            needSep = true;
13252            printedAnything = true;
13253        }
13254
13255        if (!printedAnything) {
13256            pw.println("  (nothing)");
13257        }
13258    }
13259
13260    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13261            int opti, boolean dumpAll, String dumpPackage) {
13262        boolean needSep;
13263        boolean printedAnything = false;
13264
13265        ItemMatcher matcher = new ItemMatcher();
13266        matcher.build(args, opti);
13267
13268        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13269
13270        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13271        printedAnything |= needSep;
13272
13273        if (mLaunchingProviders.size() > 0) {
13274            boolean printed = false;
13275            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13276                ContentProviderRecord r = mLaunchingProviders.get(i);
13277                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13278                    continue;
13279                }
13280                if (!printed) {
13281                    if (needSep) pw.println();
13282                    needSep = true;
13283                    pw.println("  Launching content providers:");
13284                    printed = true;
13285                    printedAnything = true;
13286                }
13287                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13288                        pw.println(r);
13289            }
13290        }
13291
13292        if (mGrantedUriPermissions.size() > 0) {
13293            boolean printed = false;
13294            int dumpUid = -2;
13295            if (dumpPackage != null) {
13296                try {
13297                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13298                } catch (NameNotFoundException e) {
13299                    dumpUid = -1;
13300                }
13301            }
13302            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13303                int uid = mGrantedUriPermissions.keyAt(i);
13304                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13305                    continue;
13306                }
13307                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13308                if (!printed) {
13309                    if (needSep) pw.println();
13310                    needSep = true;
13311                    pw.println("  Granted Uri Permissions:");
13312                    printed = true;
13313                    printedAnything = true;
13314                }
13315                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13316                for (UriPermission perm : perms.values()) {
13317                    pw.print("    "); pw.println(perm);
13318                    if (dumpAll) {
13319                        perm.dump(pw, "      ");
13320                    }
13321                }
13322            }
13323        }
13324
13325        if (!printedAnything) {
13326            pw.println("  (nothing)");
13327        }
13328    }
13329
13330    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13331            int opti, boolean dumpAll, String dumpPackage) {
13332        boolean printed = false;
13333
13334        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13335
13336        if (mIntentSenderRecords.size() > 0) {
13337            Iterator<WeakReference<PendingIntentRecord>> it
13338                    = mIntentSenderRecords.values().iterator();
13339            while (it.hasNext()) {
13340                WeakReference<PendingIntentRecord> ref = it.next();
13341                PendingIntentRecord rec = ref != null ? ref.get(): null;
13342                if (dumpPackage != null && (rec == null
13343                        || !dumpPackage.equals(rec.key.packageName))) {
13344                    continue;
13345                }
13346                printed = true;
13347                if (rec != null) {
13348                    pw.print("  * "); pw.println(rec);
13349                    if (dumpAll) {
13350                        rec.dump(pw, "    ");
13351                    }
13352                } else {
13353                    pw.print("  * "); pw.println(ref);
13354                }
13355            }
13356        }
13357
13358        if (!printed) {
13359            pw.println("  (nothing)");
13360        }
13361    }
13362
13363    private static final int dumpProcessList(PrintWriter pw,
13364            ActivityManagerService service, List list,
13365            String prefix, String normalLabel, String persistentLabel,
13366            String dumpPackage) {
13367        int numPers = 0;
13368        final int N = list.size()-1;
13369        for (int i=N; i>=0; i--) {
13370            ProcessRecord r = (ProcessRecord)list.get(i);
13371            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13372                continue;
13373            }
13374            pw.println(String.format("%s%s #%2d: %s",
13375                    prefix, (r.persistent ? persistentLabel : normalLabel),
13376                    i, r.toString()));
13377            if (r.persistent) {
13378                numPers++;
13379            }
13380        }
13381        return numPers;
13382    }
13383
13384    private static final boolean dumpProcessOomList(PrintWriter pw,
13385            ActivityManagerService service, List<ProcessRecord> origList,
13386            String prefix, String normalLabel, String persistentLabel,
13387            boolean inclDetails, String dumpPackage) {
13388
13389        ArrayList<Pair<ProcessRecord, Integer>> list
13390                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13391        for (int i=0; i<origList.size(); i++) {
13392            ProcessRecord r = origList.get(i);
13393            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13394                continue;
13395            }
13396            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13397        }
13398
13399        if (list.size() <= 0) {
13400            return false;
13401        }
13402
13403        Comparator<Pair<ProcessRecord, Integer>> comparator
13404                = new Comparator<Pair<ProcessRecord, Integer>>() {
13405            @Override
13406            public int compare(Pair<ProcessRecord, Integer> object1,
13407                    Pair<ProcessRecord, Integer> object2) {
13408                if (object1.first.setAdj != object2.first.setAdj) {
13409                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13410                }
13411                if (object1.second.intValue() != object2.second.intValue()) {
13412                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13413                }
13414                return 0;
13415            }
13416        };
13417
13418        Collections.sort(list, comparator);
13419
13420        final long curRealtime = SystemClock.elapsedRealtime();
13421        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13422        final long curUptime = SystemClock.uptimeMillis();
13423        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13424
13425        for (int i=list.size()-1; i>=0; i--) {
13426            ProcessRecord r = list.get(i).first;
13427            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13428            char schedGroup;
13429            switch (r.setSchedGroup) {
13430                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13431                    schedGroup = 'B';
13432                    break;
13433                case Process.THREAD_GROUP_DEFAULT:
13434                    schedGroup = 'F';
13435                    break;
13436                default:
13437                    schedGroup = '?';
13438                    break;
13439            }
13440            char foreground;
13441            if (r.foregroundActivities) {
13442                foreground = 'A';
13443            } else if (r.foregroundServices) {
13444                foreground = 'S';
13445            } else {
13446                foreground = ' ';
13447            }
13448            String procState = ProcessList.makeProcStateString(r.curProcState);
13449            pw.print(prefix);
13450            pw.print(r.persistent ? persistentLabel : normalLabel);
13451            pw.print(" #");
13452            int num = (origList.size()-1)-list.get(i).second;
13453            if (num < 10) pw.print(' ');
13454            pw.print(num);
13455            pw.print(": ");
13456            pw.print(oomAdj);
13457            pw.print(' ');
13458            pw.print(schedGroup);
13459            pw.print('/');
13460            pw.print(foreground);
13461            pw.print('/');
13462            pw.print(procState);
13463            pw.print(" trm:");
13464            if (r.trimMemoryLevel < 10) pw.print(' ');
13465            pw.print(r.trimMemoryLevel);
13466            pw.print(' ');
13467            pw.print(r.toShortString());
13468            pw.print(" (");
13469            pw.print(r.adjType);
13470            pw.println(')');
13471            if (r.adjSource != null || r.adjTarget != null) {
13472                pw.print(prefix);
13473                pw.print("    ");
13474                if (r.adjTarget instanceof ComponentName) {
13475                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13476                } else if (r.adjTarget != null) {
13477                    pw.print(r.adjTarget.toString());
13478                } else {
13479                    pw.print("{null}");
13480                }
13481                pw.print("<=");
13482                if (r.adjSource instanceof ProcessRecord) {
13483                    pw.print("Proc{");
13484                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13485                    pw.println("}");
13486                } else if (r.adjSource != null) {
13487                    pw.println(r.adjSource.toString());
13488                } else {
13489                    pw.println("{null}");
13490                }
13491            }
13492            if (inclDetails) {
13493                pw.print(prefix);
13494                pw.print("    ");
13495                pw.print("oom: max="); pw.print(r.maxAdj);
13496                pw.print(" curRaw="); pw.print(r.curRawAdj);
13497                pw.print(" setRaw="); pw.print(r.setRawAdj);
13498                pw.print(" cur="); pw.print(r.curAdj);
13499                pw.print(" set="); pw.println(r.setAdj);
13500                pw.print(prefix);
13501                pw.print("    ");
13502                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13503                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13504                pw.print(" lastPss="); pw.print(r.lastPss);
13505                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13506                pw.print(prefix);
13507                pw.print("    ");
13508                pw.print("cached="); pw.print(r.cached);
13509                pw.print(" empty="); pw.print(r.empty);
13510                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13511
13512                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13513                    if (r.lastWakeTime != 0) {
13514                        long wtime;
13515                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13516                        synchronized (stats) {
13517                            wtime = stats.getProcessWakeTime(r.info.uid,
13518                                    r.pid, curRealtime);
13519                        }
13520                        long timeUsed = wtime - r.lastWakeTime;
13521                        pw.print(prefix);
13522                        pw.print("    ");
13523                        pw.print("keep awake over ");
13524                        TimeUtils.formatDuration(realtimeSince, pw);
13525                        pw.print(" used ");
13526                        TimeUtils.formatDuration(timeUsed, pw);
13527                        pw.print(" (");
13528                        pw.print((timeUsed*100)/realtimeSince);
13529                        pw.println("%)");
13530                    }
13531                    if (r.lastCpuTime != 0) {
13532                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13533                        pw.print(prefix);
13534                        pw.print("    ");
13535                        pw.print("run cpu over ");
13536                        TimeUtils.formatDuration(uptimeSince, pw);
13537                        pw.print(" used ");
13538                        TimeUtils.formatDuration(timeUsed, pw);
13539                        pw.print(" (");
13540                        pw.print((timeUsed*100)/uptimeSince);
13541                        pw.println("%)");
13542                    }
13543                }
13544            }
13545        }
13546        return true;
13547    }
13548
13549    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13550        ArrayList<ProcessRecord> procs;
13551        synchronized (this) {
13552            if (args != null && args.length > start
13553                    && args[start].charAt(0) != '-') {
13554                procs = new ArrayList<ProcessRecord>();
13555                int pid = -1;
13556                try {
13557                    pid = Integer.parseInt(args[start]);
13558                } catch (NumberFormatException e) {
13559                }
13560                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13561                    ProcessRecord proc = mLruProcesses.get(i);
13562                    if (proc.pid == pid) {
13563                        procs.add(proc);
13564                    } else if (proc.processName.equals(args[start])) {
13565                        procs.add(proc);
13566                    }
13567                }
13568                if (procs.size() <= 0) {
13569                    return null;
13570                }
13571            } else {
13572                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13573            }
13574        }
13575        return procs;
13576    }
13577
13578    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13579            PrintWriter pw, String[] args) {
13580        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13581        if (procs == null) {
13582            pw.println("No process found for: " + args[0]);
13583            return;
13584        }
13585
13586        long uptime = SystemClock.uptimeMillis();
13587        long realtime = SystemClock.elapsedRealtime();
13588        pw.println("Applications Graphics Acceleration Info:");
13589        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13590
13591        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13592            ProcessRecord r = procs.get(i);
13593            if (r.thread != null) {
13594                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13595                pw.flush();
13596                try {
13597                    TransferPipe tp = new TransferPipe();
13598                    try {
13599                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13600                        tp.go(fd);
13601                    } finally {
13602                        tp.kill();
13603                    }
13604                } catch (IOException e) {
13605                    pw.println("Failure while dumping the app: " + r);
13606                    pw.flush();
13607                } catch (RemoteException e) {
13608                    pw.println("Got a RemoteException while dumping the app " + r);
13609                    pw.flush();
13610                }
13611            }
13612        }
13613    }
13614
13615    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13616        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13617        if (procs == null) {
13618            pw.println("No process found for: " + args[0]);
13619            return;
13620        }
13621
13622        pw.println("Applications Database Info:");
13623
13624        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13625            ProcessRecord r = procs.get(i);
13626            if (r.thread != null) {
13627                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13628                pw.flush();
13629                try {
13630                    TransferPipe tp = new TransferPipe();
13631                    try {
13632                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13633                        tp.go(fd);
13634                    } finally {
13635                        tp.kill();
13636                    }
13637                } catch (IOException e) {
13638                    pw.println("Failure while dumping the app: " + r);
13639                    pw.flush();
13640                } catch (RemoteException e) {
13641                    pw.println("Got a RemoteException while dumping the app " + r);
13642                    pw.flush();
13643                }
13644            }
13645        }
13646    }
13647
13648    final static class MemItem {
13649        final boolean isProc;
13650        final String label;
13651        final String shortLabel;
13652        final long pss;
13653        final int id;
13654        final boolean hasActivities;
13655        ArrayList<MemItem> subitems;
13656
13657        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13658                boolean _hasActivities) {
13659            isProc = true;
13660            label = _label;
13661            shortLabel = _shortLabel;
13662            pss = _pss;
13663            id = _id;
13664            hasActivities = _hasActivities;
13665        }
13666
13667        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13668            isProc = false;
13669            label = _label;
13670            shortLabel = _shortLabel;
13671            pss = _pss;
13672            id = _id;
13673            hasActivities = false;
13674        }
13675    }
13676
13677    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13678            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13679        if (sort && !isCompact) {
13680            Collections.sort(items, new Comparator<MemItem>() {
13681                @Override
13682                public int compare(MemItem lhs, MemItem rhs) {
13683                    if (lhs.pss < rhs.pss) {
13684                        return 1;
13685                    } else if (lhs.pss > rhs.pss) {
13686                        return -1;
13687                    }
13688                    return 0;
13689                }
13690            });
13691        }
13692
13693        for (int i=0; i<items.size(); i++) {
13694            MemItem mi = items.get(i);
13695            if (!isCompact) {
13696                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13697            } else if (mi.isProc) {
13698                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13699                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13700                pw.println(mi.hasActivities ? ",a" : ",e");
13701            } else {
13702                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13703                pw.println(mi.pss);
13704            }
13705            if (mi.subitems != null) {
13706                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13707                        true, isCompact);
13708            }
13709        }
13710    }
13711
13712    // These are in KB.
13713    static final long[] DUMP_MEM_BUCKETS = new long[] {
13714        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13715        120*1024, 160*1024, 200*1024,
13716        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13717        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13718    };
13719
13720    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13721            boolean stackLike) {
13722        int start = label.lastIndexOf('.');
13723        if (start >= 0) start++;
13724        else start = 0;
13725        int end = label.length();
13726        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13727            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13728                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13729                out.append(bucket);
13730                out.append(stackLike ? "MB." : "MB ");
13731                out.append(label, start, end);
13732                return;
13733            }
13734        }
13735        out.append(memKB/1024);
13736        out.append(stackLike ? "MB." : "MB ");
13737        out.append(label, start, end);
13738    }
13739
13740    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13741            ProcessList.NATIVE_ADJ,
13742            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13743            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13744            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13745            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13746            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13747    };
13748    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13749            "Native",
13750            "System", "Persistent", "Foreground",
13751            "Visible", "Perceptible",
13752            "Heavy Weight", "Backup",
13753            "A Services", "Home",
13754            "Previous", "B Services", "Cached"
13755    };
13756    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13757            "native",
13758            "sys", "pers", "fore",
13759            "vis", "percept",
13760            "heavy", "backup",
13761            "servicea", "home",
13762            "prev", "serviceb", "cached"
13763    };
13764
13765    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13766            long realtime, boolean isCheckinRequest, boolean isCompact) {
13767        if (isCheckinRequest || isCompact) {
13768            // short checkin version
13769            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13770        } else {
13771            pw.println("Applications Memory Usage (kB):");
13772            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13773        }
13774    }
13775
13776    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13777            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13778        boolean dumpDetails = false;
13779        boolean dumpFullDetails = false;
13780        boolean dumpDalvik = false;
13781        boolean oomOnly = false;
13782        boolean isCompact = false;
13783        boolean localOnly = false;
13784
13785        int opti = 0;
13786        while (opti < args.length) {
13787            String opt = args[opti];
13788            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13789                break;
13790            }
13791            opti++;
13792            if ("-a".equals(opt)) {
13793                dumpDetails = true;
13794                dumpFullDetails = true;
13795                dumpDalvik = true;
13796            } else if ("-d".equals(opt)) {
13797                dumpDalvik = true;
13798            } else if ("-c".equals(opt)) {
13799                isCompact = true;
13800            } else if ("--oom".equals(opt)) {
13801                oomOnly = true;
13802            } else if ("--local".equals(opt)) {
13803                localOnly = true;
13804            } else if ("-h".equals(opt)) {
13805                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13806                pw.println("  -a: include all available information for each process.");
13807                pw.println("  -d: include dalvik details when dumping process details.");
13808                pw.println("  -c: dump in a compact machine-parseable representation.");
13809                pw.println("  --oom: only show processes organized by oom adj.");
13810                pw.println("  --local: only collect details locally, don't call process.");
13811                pw.println("If [process] is specified it can be the name or ");
13812                pw.println("pid of a specific process to dump.");
13813                return;
13814            } else {
13815                pw.println("Unknown argument: " + opt + "; use -h for help");
13816            }
13817        }
13818
13819        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13820        long uptime = SystemClock.uptimeMillis();
13821        long realtime = SystemClock.elapsedRealtime();
13822        final long[] tmpLong = new long[1];
13823
13824        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13825        if (procs == null) {
13826            // No Java processes.  Maybe they want to print a native process.
13827            if (args != null && args.length > opti
13828                    && args[opti].charAt(0) != '-') {
13829                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13830                        = new ArrayList<ProcessCpuTracker.Stats>();
13831                updateCpuStatsNow();
13832                int findPid = -1;
13833                try {
13834                    findPid = Integer.parseInt(args[opti]);
13835                } catch (NumberFormatException e) {
13836                }
13837                synchronized (mProcessCpuTracker) {
13838                    final int N = mProcessCpuTracker.countStats();
13839                    for (int i=0; i<N; i++) {
13840                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13841                        if (st.pid == findPid || (st.baseName != null
13842                                && st.baseName.equals(args[opti]))) {
13843                            nativeProcs.add(st);
13844                        }
13845                    }
13846                }
13847                if (nativeProcs.size() > 0) {
13848                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13849                            isCompact);
13850                    Debug.MemoryInfo mi = null;
13851                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13852                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13853                        final int pid = r.pid;
13854                        if (!isCheckinRequest && dumpDetails) {
13855                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13856                        }
13857                        if (mi == null) {
13858                            mi = new Debug.MemoryInfo();
13859                        }
13860                        if (dumpDetails || (!brief && !oomOnly)) {
13861                            Debug.getMemoryInfo(pid, mi);
13862                        } else {
13863                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13864                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13865                        }
13866                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13867                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13868                        if (isCheckinRequest) {
13869                            pw.println();
13870                        }
13871                    }
13872                    return;
13873                }
13874            }
13875            pw.println("No process found for: " + args[opti]);
13876            return;
13877        }
13878
13879        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13880            dumpDetails = true;
13881        }
13882
13883        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13884
13885        String[] innerArgs = new String[args.length-opti];
13886        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13887
13888        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13889        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13890        long nativePss=0, dalvikPss=0, otherPss=0;
13891        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13892
13893        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13894        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13895                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13896
13897        long totalPss = 0;
13898        long cachedPss = 0;
13899
13900        Debug.MemoryInfo mi = null;
13901        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13902            final ProcessRecord r = procs.get(i);
13903            final IApplicationThread thread;
13904            final int pid;
13905            final int oomAdj;
13906            final boolean hasActivities;
13907            synchronized (this) {
13908                thread = r.thread;
13909                pid = r.pid;
13910                oomAdj = r.getSetAdjWithServices();
13911                hasActivities = r.activities.size() > 0;
13912            }
13913            if (thread != null) {
13914                if (!isCheckinRequest && dumpDetails) {
13915                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13916                }
13917                if (mi == null) {
13918                    mi = new Debug.MemoryInfo();
13919                }
13920                if (dumpDetails || (!brief && !oomOnly)) {
13921                    Debug.getMemoryInfo(pid, mi);
13922                } else {
13923                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13924                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13925                }
13926                if (dumpDetails) {
13927                    if (localOnly) {
13928                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13929                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13930                        if (isCheckinRequest) {
13931                            pw.println();
13932                        }
13933                    } else {
13934                        try {
13935                            pw.flush();
13936                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13937                                    dumpDalvik, innerArgs);
13938                        } catch (RemoteException e) {
13939                            if (!isCheckinRequest) {
13940                                pw.println("Got RemoteException!");
13941                                pw.flush();
13942                            }
13943                        }
13944                    }
13945                }
13946
13947                final long myTotalPss = mi.getTotalPss();
13948                final long myTotalUss = mi.getTotalUss();
13949
13950                synchronized (this) {
13951                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13952                        // Record this for posterity if the process has been stable.
13953                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13954                    }
13955                }
13956
13957                if (!isCheckinRequest && mi != null) {
13958                    totalPss += myTotalPss;
13959                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13960                            (hasActivities ? " / activities)" : ")"),
13961                            r.processName, myTotalPss, pid, hasActivities);
13962                    procMems.add(pssItem);
13963                    procMemsMap.put(pid, pssItem);
13964
13965                    nativePss += mi.nativePss;
13966                    dalvikPss += mi.dalvikPss;
13967                    otherPss += mi.otherPss;
13968                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13969                        long mem = mi.getOtherPss(j);
13970                        miscPss[j] += mem;
13971                        otherPss -= mem;
13972                    }
13973
13974                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13975                        cachedPss += myTotalPss;
13976                    }
13977
13978                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13979                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13980                                || oomIndex == (oomPss.length-1)) {
13981                            oomPss[oomIndex] += myTotalPss;
13982                            if (oomProcs[oomIndex] == null) {
13983                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13984                            }
13985                            oomProcs[oomIndex].add(pssItem);
13986                            break;
13987                        }
13988                    }
13989                }
13990            }
13991        }
13992
13993        long nativeProcTotalPss = 0;
13994
13995        if (!isCheckinRequest && procs.size() > 1) {
13996            // If we are showing aggregations, also look for native processes to
13997            // include so that our aggregations are more accurate.
13998            updateCpuStatsNow();
13999            synchronized (mProcessCpuTracker) {
14000                final int N = mProcessCpuTracker.countStats();
14001                for (int i=0; i<N; i++) {
14002                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14003                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14004                        if (mi == null) {
14005                            mi = new Debug.MemoryInfo();
14006                        }
14007                        if (!brief && !oomOnly) {
14008                            Debug.getMemoryInfo(st.pid, mi);
14009                        } else {
14010                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14011                            mi.nativePrivateDirty = (int)tmpLong[0];
14012                        }
14013
14014                        final long myTotalPss = mi.getTotalPss();
14015                        totalPss += myTotalPss;
14016                        nativeProcTotalPss += myTotalPss;
14017
14018                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14019                                st.name, myTotalPss, st.pid, false);
14020                        procMems.add(pssItem);
14021
14022                        nativePss += mi.nativePss;
14023                        dalvikPss += mi.dalvikPss;
14024                        otherPss += mi.otherPss;
14025                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14026                            long mem = mi.getOtherPss(j);
14027                            miscPss[j] += mem;
14028                            otherPss -= mem;
14029                        }
14030                        oomPss[0] += myTotalPss;
14031                        if (oomProcs[0] == null) {
14032                            oomProcs[0] = new ArrayList<MemItem>();
14033                        }
14034                        oomProcs[0].add(pssItem);
14035                    }
14036                }
14037            }
14038
14039            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14040
14041            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14042            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14043            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14044            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14045                String label = Debug.MemoryInfo.getOtherLabel(j);
14046                catMems.add(new MemItem(label, label, miscPss[j], j));
14047            }
14048
14049            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14050            for (int j=0; j<oomPss.length; j++) {
14051                if (oomPss[j] != 0) {
14052                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14053                            : DUMP_MEM_OOM_LABEL[j];
14054                    MemItem item = new MemItem(label, label, oomPss[j],
14055                            DUMP_MEM_OOM_ADJ[j]);
14056                    item.subitems = oomProcs[j];
14057                    oomMems.add(item);
14058                }
14059            }
14060
14061            if (!brief && !oomOnly && !isCompact) {
14062                pw.println();
14063                pw.println("Total PSS by process:");
14064                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14065                pw.println();
14066            }
14067            if (!isCompact) {
14068                pw.println("Total PSS by OOM adjustment:");
14069            }
14070            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14071            if (!brief && !oomOnly) {
14072                PrintWriter out = categoryPw != null ? categoryPw : pw;
14073                if (!isCompact) {
14074                    out.println();
14075                    out.println("Total PSS by category:");
14076                }
14077                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14078            }
14079            if (!isCompact) {
14080                pw.println();
14081            }
14082            MemInfoReader memInfo = new MemInfoReader();
14083            memInfo.readMemInfo();
14084            if (nativeProcTotalPss > 0) {
14085                synchronized (this) {
14086                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14087                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14088                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14089                            nativeProcTotalPss);
14090                }
14091            }
14092            if (!brief) {
14093                if (!isCompact) {
14094                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14095                    pw.print(" kB (status ");
14096                    switch (mLastMemoryLevel) {
14097                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14098                            pw.println("normal)");
14099                            break;
14100                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14101                            pw.println("moderate)");
14102                            break;
14103                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14104                            pw.println("low)");
14105                            break;
14106                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14107                            pw.println("critical)");
14108                            break;
14109                        default:
14110                            pw.print(mLastMemoryLevel);
14111                            pw.println(")");
14112                            break;
14113                    }
14114                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14115                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14116                            pw.print(cachedPss); pw.print(" cached pss + ");
14117                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14118                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14119                } else {
14120                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14121                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14122                            + memInfo.getFreeSizeKb()); pw.print(",");
14123                    pw.println(totalPss - cachedPss);
14124                }
14125            }
14126            if (!isCompact) {
14127                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14128                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14129                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14130                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14131                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14132                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14133                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14134                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14135                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14136                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14137                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14138            }
14139            if (!brief) {
14140                if (memInfo.getZramTotalSizeKb() != 0) {
14141                    if (!isCompact) {
14142                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14143                                pw.print(" kB physical used for ");
14144                                pw.print(memInfo.getSwapTotalSizeKb()
14145                                        - memInfo.getSwapFreeSizeKb());
14146                                pw.print(" kB in swap (");
14147                                pw.print(memInfo.getSwapTotalSizeKb());
14148                                pw.println(" kB total swap)");
14149                    } else {
14150                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14151                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14152                                pw.println(memInfo.getSwapFreeSizeKb());
14153                    }
14154                }
14155                final int[] SINGLE_LONG_FORMAT = new int[] {
14156                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14157                };
14158                long[] longOut = new long[1];
14159                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14160                        SINGLE_LONG_FORMAT, null, longOut, null);
14161                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14162                longOut[0] = 0;
14163                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14164                        SINGLE_LONG_FORMAT, null, longOut, null);
14165                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14166                longOut[0] = 0;
14167                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14168                        SINGLE_LONG_FORMAT, null, longOut, null);
14169                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14170                longOut[0] = 0;
14171                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14172                        SINGLE_LONG_FORMAT, null, longOut, null);
14173                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14174                if (!isCompact) {
14175                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14176                        pw.print("      KSM: "); pw.print(sharing);
14177                                pw.print(" kB saved from shared ");
14178                                pw.print(shared); pw.println(" kB");
14179                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14180                                pw.print(voltile); pw.println(" kB volatile");
14181                    }
14182                    pw.print("   Tuning: ");
14183                    pw.print(ActivityManager.staticGetMemoryClass());
14184                    pw.print(" (large ");
14185                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14186                    pw.print("), oom ");
14187                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14188                    pw.print(" kB");
14189                    pw.print(", restore limit ");
14190                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14191                    pw.print(" kB");
14192                    if (ActivityManager.isLowRamDeviceStatic()) {
14193                        pw.print(" (low-ram)");
14194                    }
14195                    if (ActivityManager.isHighEndGfx()) {
14196                        pw.print(" (high-end-gfx)");
14197                    }
14198                    pw.println();
14199                } else {
14200                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14201                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14202                    pw.println(voltile);
14203                    pw.print("tuning,");
14204                    pw.print(ActivityManager.staticGetMemoryClass());
14205                    pw.print(',');
14206                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14207                    pw.print(',');
14208                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14209                    if (ActivityManager.isLowRamDeviceStatic()) {
14210                        pw.print(",low-ram");
14211                    }
14212                    if (ActivityManager.isHighEndGfx()) {
14213                        pw.print(",high-end-gfx");
14214                    }
14215                    pw.println();
14216                }
14217            }
14218        }
14219    }
14220
14221    /**
14222     * Searches array of arguments for the specified string
14223     * @param args array of argument strings
14224     * @param value value to search for
14225     * @return true if the value is contained in the array
14226     */
14227    private static boolean scanArgs(String[] args, String value) {
14228        if (args != null) {
14229            for (String arg : args) {
14230                if (value.equals(arg)) {
14231                    return true;
14232                }
14233            }
14234        }
14235        return false;
14236    }
14237
14238    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14239            ContentProviderRecord cpr, boolean always) {
14240        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14241
14242        if (!inLaunching || always) {
14243            synchronized (cpr) {
14244                cpr.launchingApp = null;
14245                cpr.notifyAll();
14246            }
14247            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14248            String names[] = cpr.info.authority.split(";");
14249            for (int j = 0; j < names.length; j++) {
14250                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14251            }
14252        }
14253
14254        for (int i=0; i<cpr.connections.size(); i++) {
14255            ContentProviderConnection conn = cpr.connections.get(i);
14256            if (conn.waiting) {
14257                // If this connection is waiting for the provider, then we don't
14258                // need to mess with its process unless we are always removing
14259                // or for some reason the provider is not currently launching.
14260                if (inLaunching && !always) {
14261                    continue;
14262                }
14263            }
14264            ProcessRecord capp = conn.client;
14265            conn.dead = true;
14266            if (conn.stableCount > 0) {
14267                if (!capp.persistent && capp.thread != null
14268                        && capp.pid != 0
14269                        && capp.pid != MY_PID) {
14270                    capp.kill("depends on provider "
14271                            + cpr.name.flattenToShortString()
14272                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14273                }
14274            } else if (capp.thread != null && conn.provider.provider != null) {
14275                try {
14276                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14277                } catch (RemoteException e) {
14278                }
14279                // In the protocol here, we don't expect the client to correctly
14280                // clean up this connection, we'll just remove it.
14281                cpr.connections.remove(i);
14282                conn.client.conProviders.remove(conn);
14283            }
14284        }
14285
14286        if (inLaunching && always) {
14287            mLaunchingProviders.remove(cpr);
14288        }
14289        return inLaunching;
14290    }
14291
14292    /**
14293     * Main code for cleaning up a process when it has gone away.  This is
14294     * called both as a result of the process dying, or directly when stopping
14295     * a process when running in single process mode.
14296     */
14297    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14298            boolean restarting, boolean allowRestart, int index) {
14299        if (index >= 0) {
14300            removeLruProcessLocked(app);
14301            ProcessList.remove(app.pid);
14302        }
14303
14304        mProcessesToGc.remove(app);
14305        mPendingPssProcesses.remove(app);
14306
14307        // Dismiss any open dialogs.
14308        if (app.crashDialog != null && !app.forceCrashReport) {
14309            app.crashDialog.dismiss();
14310            app.crashDialog = null;
14311        }
14312        if (app.anrDialog != null) {
14313            app.anrDialog.dismiss();
14314            app.anrDialog = null;
14315        }
14316        if (app.waitDialog != null) {
14317            app.waitDialog.dismiss();
14318            app.waitDialog = null;
14319        }
14320
14321        app.crashing = false;
14322        app.notResponding = false;
14323
14324        app.resetPackageList(mProcessStats);
14325        app.unlinkDeathRecipient();
14326        app.makeInactive(mProcessStats);
14327        app.waitingToKill = null;
14328        app.forcingToForeground = null;
14329        updateProcessForegroundLocked(app, false, false);
14330        app.foregroundActivities = false;
14331        app.hasShownUi = false;
14332        app.treatLikeActivity = false;
14333        app.hasAboveClient = false;
14334        app.hasClientActivities = false;
14335
14336        mServices.killServicesLocked(app, allowRestart);
14337
14338        boolean restart = false;
14339
14340        // Remove published content providers.
14341        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14342            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14343            final boolean always = app.bad || !allowRestart;
14344            if (removeDyingProviderLocked(app, cpr, always) || always) {
14345                // We left the provider in the launching list, need to
14346                // restart it.
14347                restart = true;
14348            }
14349
14350            cpr.provider = null;
14351            cpr.proc = null;
14352        }
14353        app.pubProviders.clear();
14354
14355        // Take care of any launching providers waiting for this process.
14356        if (checkAppInLaunchingProvidersLocked(app, false)) {
14357            restart = true;
14358        }
14359
14360        // Unregister from connected content providers.
14361        if (!app.conProviders.isEmpty()) {
14362            for (int i=0; i<app.conProviders.size(); i++) {
14363                ContentProviderConnection conn = app.conProviders.get(i);
14364                conn.provider.connections.remove(conn);
14365            }
14366            app.conProviders.clear();
14367        }
14368
14369        // At this point there may be remaining entries in mLaunchingProviders
14370        // where we were the only one waiting, so they are no longer of use.
14371        // Look for these and clean up if found.
14372        // XXX Commented out for now.  Trying to figure out a way to reproduce
14373        // the actual situation to identify what is actually going on.
14374        if (false) {
14375            for (int i=0; i<mLaunchingProviders.size(); i++) {
14376                ContentProviderRecord cpr = (ContentProviderRecord)
14377                        mLaunchingProviders.get(i);
14378                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14379                    synchronized (cpr) {
14380                        cpr.launchingApp = null;
14381                        cpr.notifyAll();
14382                    }
14383                }
14384            }
14385        }
14386
14387        skipCurrentReceiverLocked(app);
14388
14389        // Unregister any receivers.
14390        for (int i=app.receivers.size()-1; i>=0; i--) {
14391            removeReceiverLocked(app.receivers.valueAt(i));
14392        }
14393        app.receivers.clear();
14394
14395        // If the app is undergoing backup, tell the backup manager about it
14396        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14397            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14398                    + mBackupTarget.appInfo + " died during backup");
14399            try {
14400                IBackupManager bm = IBackupManager.Stub.asInterface(
14401                        ServiceManager.getService(Context.BACKUP_SERVICE));
14402                bm.agentDisconnected(app.info.packageName);
14403            } catch (RemoteException e) {
14404                // can't happen; backup manager is local
14405            }
14406        }
14407
14408        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14409            ProcessChangeItem item = mPendingProcessChanges.get(i);
14410            if (item.pid == app.pid) {
14411                mPendingProcessChanges.remove(i);
14412                mAvailProcessChanges.add(item);
14413            }
14414        }
14415        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14416
14417        // If the caller is restarting this app, then leave it in its
14418        // current lists and let the caller take care of it.
14419        if (restarting) {
14420            return;
14421        }
14422
14423        if (!app.persistent || app.isolated) {
14424            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14425                    "Removing non-persistent process during cleanup: " + app);
14426            mProcessNames.remove(app.processName, app.uid);
14427            mIsolatedProcesses.remove(app.uid);
14428            if (mHeavyWeightProcess == app) {
14429                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14430                        mHeavyWeightProcess.userId, 0));
14431                mHeavyWeightProcess = null;
14432            }
14433        } else if (!app.removed) {
14434            // This app is persistent, so we need to keep its record around.
14435            // If it is not already on the pending app list, add it there
14436            // and start a new process for it.
14437            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14438                mPersistentStartingProcesses.add(app);
14439                restart = true;
14440            }
14441        }
14442        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14443                "Clean-up removing on hold: " + app);
14444        mProcessesOnHold.remove(app);
14445
14446        if (app == mHomeProcess) {
14447            mHomeProcess = null;
14448        }
14449        if (app == mPreviousProcess) {
14450            mPreviousProcess = null;
14451        }
14452
14453        if (restart && !app.isolated) {
14454            // We have components that still need to be running in the
14455            // process, so re-launch it.
14456            mProcessNames.put(app.processName, app.uid, app);
14457            startProcessLocked(app, "restart", app.processName);
14458        } else if (app.pid > 0 && app.pid != MY_PID) {
14459            // Goodbye!
14460            boolean removed;
14461            synchronized (mPidsSelfLocked) {
14462                mPidsSelfLocked.remove(app.pid);
14463                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14464            }
14465            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14466            if (app.isolated) {
14467                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14468            }
14469            app.setPid(0);
14470        }
14471    }
14472
14473    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14474        // Look through the content providers we are waiting to have launched,
14475        // and if any run in this process then either schedule a restart of
14476        // the process or kill the client waiting for it if this process has
14477        // gone bad.
14478        int NL = mLaunchingProviders.size();
14479        boolean restart = false;
14480        for (int i=0; i<NL; i++) {
14481            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14482            if (cpr.launchingApp == app) {
14483                if (!alwaysBad && !app.bad) {
14484                    restart = true;
14485                } else {
14486                    removeDyingProviderLocked(app, cpr, true);
14487                    // cpr should have been removed from mLaunchingProviders
14488                    NL = mLaunchingProviders.size();
14489                    i--;
14490                }
14491            }
14492        }
14493        return restart;
14494    }
14495
14496    // =========================================================
14497    // SERVICES
14498    // =========================================================
14499
14500    @Override
14501    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14502            int flags) {
14503        enforceNotIsolatedCaller("getServices");
14504        synchronized (this) {
14505            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14506        }
14507    }
14508
14509    @Override
14510    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14511        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14512        synchronized (this) {
14513            return mServices.getRunningServiceControlPanelLocked(name);
14514        }
14515    }
14516
14517    @Override
14518    public ComponentName startService(IApplicationThread caller, Intent service,
14519            String resolvedType, int userId) {
14520        enforceNotIsolatedCaller("startService");
14521        // Refuse possible leaked file descriptors
14522        if (service != null && service.hasFileDescriptors() == true) {
14523            throw new IllegalArgumentException("File descriptors passed in Intent");
14524        }
14525
14526        if (DEBUG_SERVICE)
14527            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14528        synchronized(this) {
14529            final int callingPid = Binder.getCallingPid();
14530            final int callingUid = Binder.getCallingUid();
14531            final long origId = Binder.clearCallingIdentity();
14532            ComponentName res = mServices.startServiceLocked(caller, service,
14533                    resolvedType, callingPid, callingUid, userId);
14534            Binder.restoreCallingIdentity(origId);
14535            return res;
14536        }
14537    }
14538
14539    ComponentName startServiceInPackage(int uid,
14540            Intent service, String resolvedType, int userId) {
14541        synchronized(this) {
14542            if (DEBUG_SERVICE)
14543                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14544            final long origId = Binder.clearCallingIdentity();
14545            ComponentName res = mServices.startServiceLocked(null, service,
14546                    resolvedType, -1, uid, userId);
14547            Binder.restoreCallingIdentity(origId);
14548            return res;
14549        }
14550    }
14551
14552    @Override
14553    public int stopService(IApplicationThread caller, Intent service,
14554            String resolvedType, int userId) {
14555        enforceNotIsolatedCaller("stopService");
14556        // Refuse possible leaked file descriptors
14557        if (service != null && service.hasFileDescriptors() == true) {
14558            throw new IllegalArgumentException("File descriptors passed in Intent");
14559        }
14560
14561        synchronized(this) {
14562            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14563        }
14564    }
14565
14566    @Override
14567    public IBinder peekService(Intent service, String resolvedType) {
14568        enforceNotIsolatedCaller("peekService");
14569        // Refuse possible leaked file descriptors
14570        if (service != null && service.hasFileDescriptors() == true) {
14571            throw new IllegalArgumentException("File descriptors passed in Intent");
14572        }
14573        synchronized(this) {
14574            return mServices.peekServiceLocked(service, resolvedType);
14575        }
14576    }
14577
14578    @Override
14579    public boolean stopServiceToken(ComponentName className, IBinder token,
14580            int startId) {
14581        synchronized(this) {
14582            return mServices.stopServiceTokenLocked(className, token, startId);
14583        }
14584    }
14585
14586    @Override
14587    public void setServiceForeground(ComponentName className, IBinder token,
14588            int id, Notification notification, boolean removeNotification) {
14589        synchronized(this) {
14590            mServices.setServiceForegroundLocked(className, token, id, notification,
14591                    removeNotification);
14592        }
14593    }
14594
14595    @Override
14596    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14597            boolean requireFull, String name, String callerPackage) {
14598        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14599                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14600    }
14601
14602    int unsafeConvertIncomingUser(int userId) {
14603        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14604                ? mCurrentUserId : userId;
14605    }
14606
14607    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14608            int allowMode, String name, String callerPackage) {
14609        final int callingUserId = UserHandle.getUserId(callingUid);
14610        if (callingUserId == userId) {
14611            return userId;
14612        }
14613
14614        // Note that we may be accessing mCurrentUserId outside of a lock...
14615        // shouldn't be a big deal, if this is being called outside
14616        // of a locked context there is intrinsically a race with
14617        // the value the caller will receive and someone else changing it.
14618        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14619        // we will switch to the calling user if access to the current user fails.
14620        int targetUserId = unsafeConvertIncomingUser(userId);
14621
14622        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14623            final boolean allow;
14624            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14625                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14626                // If the caller has this permission, they always pass go.  And collect $200.
14627                allow = true;
14628            } else if (allowMode == ALLOW_FULL_ONLY) {
14629                // We require full access, sucks to be you.
14630                allow = false;
14631            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14632                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14633                // If the caller does not have either permission, they are always doomed.
14634                allow = false;
14635            } else if (allowMode == ALLOW_NON_FULL) {
14636                // We are blanket allowing non-full access, you lucky caller!
14637                allow = true;
14638            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14639                // We may or may not allow this depending on whether the two users are
14640                // in the same profile.
14641                synchronized (mUserProfileGroupIdsSelfLocked) {
14642                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14643                            UserInfo.NO_PROFILE_GROUP_ID);
14644                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14645                            UserInfo.NO_PROFILE_GROUP_ID);
14646                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14647                            && callingProfile == targetProfile;
14648                }
14649            } else {
14650                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14651            }
14652            if (!allow) {
14653                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14654                    // In this case, they would like to just execute as their
14655                    // owner user instead of failing.
14656                    targetUserId = callingUserId;
14657                } else {
14658                    StringBuilder builder = new StringBuilder(128);
14659                    builder.append("Permission Denial: ");
14660                    builder.append(name);
14661                    if (callerPackage != null) {
14662                        builder.append(" from ");
14663                        builder.append(callerPackage);
14664                    }
14665                    builder.append(" asks to run as user ");
14666                    builder.append(userId);
14667                    builder.append(" but is calling from user ");
14668                    builder.append(UserHandle.getUserId(callingUid));
14669                    builder.append("; this requires ");
14670                    builder.append(INTERACT_ACROSS_USERS_FULL);
14671                    if (allowMode != ALLOW_FULL_ONLY) {
14672                        builder.append(" or ");
14673                        builder.append(INTERACT_ACROSS_USERS);
14674                    }
14675                    String msg = builder.toString();
14676                    Slog.w(TAG, msg);
14677                    throw new SecurityException(msg);
14678                }
14679            }
14680        }
14681        if (!allowAll && targetUserId < 0) {
14682            throw new IllegalArgumentException(
14683                    "Call does not support special user #" + targetUserId);
14684        }
14685        // Check shell permission
14686        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14687            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14688                    targetUserId)) {
14689                throw new SecurityException("Shell does not have permission to access user "
14690                        + targetUserId + "\n " + Debug.getCallers(3));
14691            }
14692        }
14693        return targetUserId;
14694    }
14695
14696    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14697            String className, int flags) {
14698        boolean result = false;
14699        // For apps that don't have pre-defined UIDs, check for permission
14700        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14701            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14702                if (ActivityManager.checkUidPermission(
14703                        INTERACT_ACROSS_USERS,
14704                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14705                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14706                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14707                            + " requests FLAG_SINGLE_USER, but app does not hold "
14708                            + INTERACT_ACROSS_USERS;
14709                    Slog.w(TAG, msg);
14710                    throw new SecurityException(msg);
14711                }
14712                // Permission passed
14713                result = true;
14714            }
14715        } else if ("system".equals(componentProcessName)) {
14716            result = true;
14717        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14718            // Phone app and persistent apps are allowed to export singleuser providers.
14719            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14720                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14721        }
14722        if (DEBUG_MU) {
14723            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14724                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14725        }
14726        return result;
14727    }
14728
14729    /**
14730     * Checks to see if the caller is in the same app as the singleton
14731     * component, or the component is in a special app. It allows special apps
14732     * to export singleton components but prevents exporting singleton
14733     * components for regular apps.
14734     */
14735    boolean isValidSingletonCall(int callingUid, int componentUid) {
14736        int componentAppId = UserHandle.getAppId(componentUid);
14737        return UserHandle.isSameApp(callingUid, componentUid)
14738                || componentAppId == Process.SYSTEM_UID
14739                || componentAppId == Process.PHONE_UID
14740                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14741                        == PackageManager.PERMISSION_GRANTED;
14742    }
14743
14744    public int bindService(IApplicationThread caller, IBinder token,
14745            Intent service, String resolvedType,
14746            IServiceConnection connection, int flags, int userId) {
14747        enforceNotIsolatedCaller("bindService");
14748
14749        // Refuse possible leaked file descriptors
14750        if (service != null && service.hasFileDescriptors() == true) {
14751            throw new IllegalArgumentException("File descriptors passed in Intent");
14752        }
14753
14754        synchronized(this) {
14755            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14756                    connection, flags, userId);
14757        }
14758    }
14759
14760    public boolean unbindService(IServiceConnection connection) {
14761        synchronized (this) {
14762            return mServices.unbindServiceLocked(connection);
14763        }
14764    }
14765
14766    public void publishService(IBinder token, Intent intent, IBinder service) {
14767        // Refuse possible leaked file descriptors
14768        if (intent != null && intent.hasFileDescriptors() == true) {
14769            throw new IllegalArgumentException("File descriptors passed in Intent");
14770        }
14771
14772        synchronized(this) {
14773            if (!(token instanceof ServiceRecord)) {
14774                throw new IllegalArgumentException("Invalid service token");
14775            }
14776            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14777        }
14778    }
14779
14780    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14781        // Refuse possible leaked file descriptors
14782        if (intent != null && intent.hasFileDescriptors() == true) {
14783            throw new IllegalArgumentException("File descriptors passed in Intent");
14784        }
14785
14786        synchronized(this) {
14787            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14788        }
14789    }
14790
14791    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14792        synchronized(this) {
14793            if (!(token instanceof ServiceRecord)) {
14794                throw new IllegalArgumentException("Invalid service token");
14795            }
14796            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14797        }
14798    }
14799
14800    // =========================================================
14801    // BACKUP AND RESTORE
14802    // =========================================================
14803
14804    // Cause the target app to be launched if necessary and its backup agent
14805    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14806    // activity manager to announce its creation.
14807    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14808        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14809        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14810
14811        synchronized(this) {
14812            // !!! TODO: currently no check here that we're already bound
14813            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14814            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14815            synchronized (stats) {
14816                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14817            }
14818
14819            // Backup agent is now in use, its package can't be stopped.
14820            try {
14821                AppGlobals.getPackageManager().setPackageStoppedState(
14822                        app.packageName, false, UserHandle.getUserId(app.uid));
14823            } catch (RemoteException e) {
14824            } catch (IllegalArgumentException e) {
14825                Slog.w(TAG, "Failed trying to unstop package "
14826                        + app.packageName + ": " + e);
14827            }
14828
14829            BackupRecord r = new BackupRecord(ss, app, backupMode);
14830            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14831                    ? new ComponentName(app.packageName, app.backupAgentName)
14832                    : new ComponentName("android", "FullBackupAgent");
14833            // startProcessLocked() returns existing proc's record if it's already running
14834            ProcessRecord proc = startProcessLocked(app.processName, app,
14835                    false, 0, "backup", hostingName, false, false, false);
14836            if (proc == null) {
14837                Slog.e(TAG, "Unable to start backup agent process " + r);
14838                return false;
14839            }
14840
14841            r.app = proc;
14842            mBackupTarget = r;
14843            mBackupAppName = app.packageName;
14844
14845            // Try not to kill the process during backup
14846            updateOomAdjLocked(proc);
14847
14848            // If the process is already attached, schedule the creation of the backup agent now.
14849            // If it is not yet live, this will be done when it attaches to the framework.
14850            if (proc.thread != null) {
14851                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14852                try {
14853                    proc.thread.scheduleCreateBackupAgent(app,
14854                            compatibilityInfoForPackageLocked(app), backupMode);
14855                } catch (RemoteException e) {
14856                    // Will time out on the backup manager side
14857                }
14858            } else {
14859                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14860            }
14861            // Invariants: at this point, the target app process exists and the application
14862            // is either already running or in the process of coming up.  mBackupTarget and
14863            // mBackupAppName describe the app, so that when it binds back to the AM we
14864            // know that it's scheduled for a backup-agent operation.
14865        }
14866
14867        return true;
14868    }
14869
14870    @Override
14871    public void clearPendingBackup() {
14872        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14873        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14874
14875        synchronized (this) {
14876            mBackupTarget = null;
14877            mBackupAppName = null;
14878        }
14879    }
14880
14881    // A backup agent has just come up
14882    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14883        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14884                + " = " + agent);
14885
14886        synchronized(this) {
14887            if (!agentPackageName.equals(mBackupAppName)) {
14888                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14889                return;
14890            }
14891        }
14892
14893        long oldIdent = Binder.clearCallingIdentity();
14894        try {
14895            IBackupManager bm = IBackupManager.Stub.asInterface(
14896                    ServiceManager.getService(Context.BACKUP_SERVICE));
14897            bm.agentConnected(agentPackageName, agent);
14898        } catch (RemoteException e) {
14899            // can't happen; the backup manager service is local
14900        } catch (Exception e) {
14901            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14902            e.printStackTrace();
14903        } finally {
14904            Binder.restoreCallingIdentity(oldIdent);
14905        }
14906    }
14907
14908    // done with this agent
14909    public void unbindBackupAgent(ApplicationInfo appInfo) {
14910        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14911        if (appInfo == null) {
14912            Slog.w(TAG, "unbind backup agent for null app");
14913            return;
14914        }
14915
14916        synchronized(this) {
14917            try {
14918                if (mBackupAppName == null) {
14919                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14920                    return;
14921                }
14922
14923                if (!mBackupAppName.equals(appInfo.packageName)) {
14924                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14925                    return;
14926                }
14927
14928                // Not backing this app up any more; reset its OOM adjustment
14929                final ProcessRecord proc = mBackupTarget.app;
14930                updateOomAdjLocked(proc);
14931
14932                // If the app crashed during backup, 'thread' will be null here
14933                if (proc.thread != null) {
14934                    try {
14935                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14936                                compatibilityInfoForPackageLocked(appInfo));
14937                    } catch (Exception e) {
14938                        Slog.e(TAG, "Exception when unbinding backup agent:");
14939                        e.printStackTrace();
14940                    }
14941                }
14942            } finally {
14943                mBackupTarget = null;
14944                mBackupAppName = null;
14945            }
14946        }
14947    }
14948    // =========================================================
14949    // BROADCASTS
14950    // =========================================================
14951
14952    private final List getStickiesLocked(String action, IntentFilter filter,
14953            List cur, int userId) {
14954        final ContentResolver resolver = mContext.getContentResolver();
14955        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14956        if (stickies == null) {
14957            return cur;
14958        }
14959        final ArrayList<Intent> list = stickies.get(action);
14960        if (list == null) {
14961            return cur;
14962        }
14963        int N = list.size();
14964        for (int i=0; i<N; i++) {
14965            Intent intent = list.get(i);
14966            if (filter.match(resolver, intent, true, TAG) >= 0) {
14967                if (cur == null) {
14968                    cur = new ArrayList<Intent>();
14969                }
14970                cur.add(intent);
14971            }
14972        }
14973        return cur;
14974    }
14975
14976    boolean isPendingBroadcastProcessLocked(int pid) {
14977        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14978                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14979    }
14980
14981    void skipPendingBroadcastLocked(int pid) {
14982            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14983            for (BroadcastQueue queue : mBroadcastQueues) {
14984                queue.skipPendingBroadcastLocked(pid);
14985            }
14986    }
14987
14988    // The app just attached; send any pending broadcasts that it should receive
14989    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14990        boolean didSomething = false;
14991        for (BroadcastQueue queue : mBroadcastQueues) {
14992            didSomething |= queue.sendPendingBroadcastsLocked(app);
14993        }
14994        return didSomething;
14995    }
14996
14997    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14998            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14999        enforceNotIsolatedCaller("registerReceiver");
15000        int callingUid;
15001        int callingPid;
15002        synchronized(this) {
15003            ProcessRecord callerApp = null;
15004            if (caller != null) {
15005                callerApp = getRecordForAppLocked(caller);
15006                if (callerApp == null) {
15007                    throw new SecurityException(
15008                            "Unable to find app for caller " + caller
15009                            + " (pid=" + Binder.getCallingPid()
15010                            + ") when registering receiver " + receiver);
15011                }
15012                if (callerApp.info.uid != Process.SYSTEM_UID &&
15013                        !callerApp.pkgList.containsKey(callerPackage) &&
15014                        !"android".equals(callerPackage)) {
15015                    throw new SecurityException("Given caller package " + callerPackage
15016                            + " is not running in process " + callerApp);
15017                }
15018                callingUid = callerApp.info.uid;
15019                callingPid = callerApp.pid;
15020            } else {
15021                callerPackage = null;
15022                callingUid = Binder.getCallingUid();
15023                callingPid = Binder.getCallingPid();
15024            }
15025
15026            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15027                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15028
15029            List allSticky = null;
15030
15031            // Look for any matching sticky broadcasts...
15032            Iterator actions = filter.actionsIterator();
15033            if (actions != null) {
15034                while (actions.hasNext()) {
15035                    String action = (String)actions.next();
15036                    allSticky = getStickiesLocked(action, filter, allSticky,
15037                            UserHandle.USER_ALL);
15038                    allSticky = getStickiesLocked(action, filter, allSticky,
15039                            UserHandle.getUserId(callingUid));
15040                }
15041            } else {
15042                allSticky = getStickiesLocked(null, filter, allSticky,
15043                        UserHandle.USER_ALL);
15044                allSticky = getStickiesLocked(null, filter, allSticky,
15045                        UserHandle.getUserId(callingUid));
15046            }
15047
15048            // The first sticky in the list is returned directly back to
15049            // the client.
15050            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15051
15052            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15053                    + ": " + sticky);
15054
15055            if (receiver == null) {
15056                return sticky;
15057            }
15058
15059            ReceiverList rl
15060                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15061            if (rl == null) {
15062                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15063                        userId, receiver);
15064                if (rl.app != null) {
15065                    rl.app.receivers.add(rl);
15066                } else {
15067                    try {
15068                        receiver.asBinder().linkToDeath(rl, 0);
15069                    } catch (RemoteException e) {
15070                        return sticky;
15071                    }
15072                    rl.linkedToDeath = true;
15073                }
15074                mRegisteredReceivers.put(receiver.asBinder(), rl);
15075            } else if (rl.uid != callingUid) {
15076                throw new IllegalArgumentException(
15077                        "Receiver requested to register for uid " + callingUid
15078                        + " was previously registered for uid " + rl.uid);
15079            } else if (rl.pid != callingPid) {
15080                throw new IllegalArgumentException(
15081                        "Receiver requested to register for pid " + callingPid
15082                        + " was previously registered for pid " + rl.pid);
15083            } else if (rl.userId != userId) {
15084                throw new IllegalArgumentException(
15085                        "Receiver requested to register for user " + userId
15086                        + " was previously registered for user " + rl.userId);
15087            }
15088            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15089                    permission, callingUid, userId);
15090            rl.add(bf);
15091            if (!bf.debugCheck()) {
15092                Slog.w(TAG, "==> For Dynamic broadast");
15093            }
15094            mReceiverResolver.addFilter(bf);
15095
15096            // Enqueue broadcasts for all existing stickies that match
15097            // this filter.
15098            if (allSticky != null) {
15099                ArrayList receivers = new ArrayList();
15100                receivers.add(bf);
15101
15102                int N = allSticky.size();
15103                for (int i=0; i<N; i++) {
15104                    Intent intent = (Intent)allSticky.get(i);
15105                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15106                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15107                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15108                            null, null, false, true, true, -1);
15109                    queue.enqueueParallelBroadcastLocked(r);
15110                    queue.scheduleBroadcastsLocked();
15111                }
15112            }
15113
15114            return sticky;
15115        }
15116    }
15117
15118    public void unregisterReceiver(IIntentReceiver receiver) {
15119        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15120
15121        final long origId = Binder.clearCallingIdentity();
15122        try {
15123            boolean doTrim = false;
15124
15125            synchronized(this) {
15126                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15127                if (rl != null) {
15128                    if (rl.curBroadcast != null) {
15129                        BroadcastRecord r = rl.curBroadcast;
15130                        final boolean doNext = finishReceiverLocked(
15131                                receiver.asBinder(), r.resultCode, r.resultData,
15132                                r.resultExtras, r.resultAbort);
15133                        if (doNext) {
15134                            doTrim = true;
15135                            r.queue.processNextBroadcast(false);
15136                        }
15137                    }
15138
15139                    if (rl.app != null) {
15140                        rl.app.receivers.remove(rl);
15141                    }
15142                    removeReceiverLocked(rl);
15143                    if (rl.linkedToDeath) {
15144                        rl.linkedToDeath = false;
15145                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15146                    }
15147                }
15148            }
15149
15150            // If we actually concluded any broadcasts, we might now be able
15151            // to trim the recipients' apps from our working set
15152            if (doTrim) {
15153                trimApplications();
15154                return;
15155            }
15156
15157        } finally {
15158            Binder.restoreCallingIdentity(origId);
15159        }
15160    }
15161
15162    void removeReceiverLocked(ReceiverList rl) {
15163        mRegisteredReceivers.remove(rl.receiver.asBinder());
15164        int N = rl.size();
15165        for (int i=0; i<N; i++) {
15166            mReceiverResolver.removeFilter(rl.get(i));
15167        }
15168    }
15169
15170    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15171        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15172            ProcessRecord r = mLruProcesses.get(i);
15173            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15174                try {
15175                    r.thread.dispatchPackageBroadcast(cmd, packages);
15176                } catch (RemoteException ex) {
15177                }
15178            }
15179        }
15180    }
15181
15182    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15183            int callingUid, int[] users) {
15184        List<ResolveInfo> receivers = null;
15185        try {
15186            HashSet<ComponentName> singleUserReceivers = null;
15187            boolean scannedFirstReceivers = false;
15188            for (int user : users) {
15189                // Skip users that have Shell restrictions
15190                if (callingUid == Process.SHELL_UID
15191                        && getUserManagerLocked().hasUserRestriction(
15192                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15193                    continue;
15194                }
15195                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15196                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15197                if (user != 0 && newReceivers != null) {
15198                    // If this is not the primary user, we need to check for
15199                    // any receivers that should be filtered out.
15200                    for (int i=0; i<newReceivers.size(); i++) {
15201                        ResolveInfo ri = newReceivers.get(i);
15202                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15203                            newReceivers.remove(i);
15204                            i--;
15205                        }
15206                    }
15207                }
15208                if (newReceivers != null && newReceivers.size() == 0) {
15209                    newReceivers = null;
15210                }
15211                if (receivers == null) {
15212                    receivers = newReceivers;
15213                } else if (newReceivers != null) {
15214                    // We need to concatenate the additional receivers
15215                    // found with what we have do far.  This would be easy,
15216                    // but we also need to de-dup any receivers that are
15217                    // singleUser.
15218                    if (!scannedFirstReceivers) {
15219                        // Collect any single user receivers we had already retrieved.
15220                        scannedFirstReceivers = true;
15221                        for (int i=0; i<receivers.size(); i++) {
15222                            ResolveInfo ri = receivers.get(i);
15223                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15224                                ComponentName cn = new ComponentName(
15225                                        ri.activityInfo.packageName, ri.activityInfo.name);
15226                                if (singleUserReceivers == null) {
15227                                    singleUserReceivers = new HashSet<ComponentName>();
15228                                }
15229                                singleUserReceivers.add(cn);
15230                            }
15231                        }
15232                    }
15233                    // Add the new results to the existing results, tracking
15234                    // and de-dupping single user receivers.
15235                    for (int i=0; i<newReceivers.size(); i++) {
15236                        ResolveInfo ri = newReceivers.get(i);
15237                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15238                            ComponentName cn = new ComponentName(
15239                                    ri.activityInfo.packageName, ri.activityInfo.name);
15240                            if (singleUserReceivers == null) {
15241                                singleUserReceivers = new HashSet<ComponentName>();
15242                            }
15243                            if (!singleUserReceivers.contains(cn)) {
15244                                singleUserReceivers.add(cn);
15245                                receivers.add(ri);
15246                            }
15247                        } else {
15248                            receivers.add(ri);
15249                        }
15250                    }
15251                }
15252            }
15253        } catch (RemoteException ex) {
15254            // pm is in same process, this will never happen.
15255        }
15256        return receivers;
15257    }
15258
15259    private final int broadcastIntentLocked(ProcessRecord callerApp,
15260            String callerPackage, Intent intent, String resolvedType,
15261            IIntentReceiver resultTo, int resultCode, String resultData,
15262            Bundle map, String requiredPermission, int appOp,
15263            boolean ordered, boolean sticky, int callingPid, int callingUid,
15264            int userId) {
15265        intent = new Intent(intent);
15266
15267        // By default broadcasts do not go to stopped apps.
15268        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15269
15270        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15271            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15272            + " ordered=" + ordered + " userid=" + userId);
15273        if ((resultTo != null) && !ordered) {
15274            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15275        }
15276
15277        userId = handleIncomingUser(callingPid, callingUid, userId,
15278                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15279
15280        // Make sure that the user who is receiving this broadcast is started.
15281        // If not, we will just skip it.
15282
15283        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15284            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15285                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15286                Slog.w(TAG, "Skipping broadcast of " + intent
15287                        + ": user " + userId + " is stopped");
15288                return ActivityManager.BROADCAST_SUCCESS;
15289            }
15290        }
15291
15292        /*
15293         * Prevent non-system code (defined here to be non-persistent
15294         * processes) from sending protected broadcasts.
15295         */
15296        int callingAppId = UserHandle.getAppId(callingUid);
15297        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15298            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15299            || callingAppId == Process.NFC_UID || callingUid == 0) {
15300            // Always okay.
15301        } else if (callerApp == null || !callerApp.persistent) {
15302            try {
15303                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15304                        intent.getAction())) {
15305                    String msg = "Permission Denial: not allowed to send broadcast "
15306                            + intent.getAction() + " from pid="
15307                            + callingPid + ", uid=" + callingUid;
15308                    Slog.w(TAG, msg);
15309                    throw new SecurityException(msg);
15310                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15311                    // Special case for compatibility: we don't want apps to send this,
15312                    // but historically it has not been protected and apps may be using it
15313                    // to poke their own app widget.  So, instead of making it protected,
15314                    // just limit it to the caller.
15315                    if (callerApp == null) {
15316                        String msg = "Permission Denial: not allowed to send broadcast "
15317                                + intent.getAction() + " from unknown caller.";
15318                        Slog.w(TAG, msg);
15319                        throw new SecurityException(msg);
15320                    } else if (intent.getComponent() != null) {
15321                        // They are good enough to send to an explicit component...  verify
15322                        // it is being sent to the calling app.
15323                        if (!intent.getComponent().getPackageName().equals(
15324                                callerApp.info.packageName)) {
15325                            String msg = "Permission Denial: not allowed to send broadcast "
15326                                    + intent.getAction() + " to "
15327                                    + intent.getComponent().getPackageName() + " from "
15328                                    + callerApp.info.packageName;
15329                            Slog.w(TAG, msg);
15330                            throw new SecurityException(msg);
15331                        }
15332                    } else {
15333                        // Limit broadcast to their own package.
15334                        intent.setPackage(callerApp.info.packageName);
15335                    }
15336                }
15337            } catch (RemoteException e) {
15338                Slog.w(TAG, "Remote exception", e);
15339                return ActivityManager.BROADCAST_SUCCESS;
15340            }
15341        }
15342
15343        // Handle special intents: if this broadcast is from the package
15344        // manager about a package being removed, we need to remove all of
15345        // its activities from the history stack.
15346        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15347                intent.getAction());
15348        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15349                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15350                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15351                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15352                || uidRemoved) {
15353            if (checkComponentPermission(
15354                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15355                    callingPid, callingUid, -1, true)
15356                    == PackageManager.PERMISSION_GRANTED) {
15357                if (uidRemoved) {
15358                    final Bundle intentExtras = intent.getExtras();
15359                    final int uid = intentExtras != null
15360                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15361                    if (uid >= 0) {
15362                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15363                        synchronized (bs) {
15364                            bs.removeUidStatsLocked(uid);
15365                        }
15366                        mAppOpsService.uidRemoved(uid);
15367                    }
15368                } else {
15369                    // If resources are unavailable just force stop all
15370                    // those packages and flush the attribute cache as well.
15371                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15372                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15373                        if (list != null && (list.length > 0)) {
15374                            for (String pkg : list) {
15375                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15376                                        "storage unmount");
15377                            }
15378                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15379                            sendPackageBroadcastLocked(
15380                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15381                        }
15382                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15383                            intent.getAction())) {
15384                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15385                    } else {
15386                        Uri data = intent.getData();
15387                        String ssp;
15388                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15389                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15390                                    intent.getAction());
15391                            boolean fullUninstall = removed &&
15392                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15393                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15394                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15395                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15396                                        false, fullUninstall, userId,
15397                                        removed ? "pkg removed" : "pkg changed");
15398                            }
15399                            if (removed) {
15400                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15401                                        new String[] {ssp}, userId);
15402                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15403                                    mAppOpsService.packageRemoved(
15404                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15405
15406                                    // Remove all permissions granted from/to this package
15407                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15408                                }
15409                            }
15410                        }
15411                    }
15412                }
15413            } else {
15414                String msg = "Permission Denial: " + intent.getAction()
15415                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15416                        + ", uid=" + callingUid + ")"
15417                        + " requires "
15418                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15419                Slog.w(TAG, msg);
15420                throw new SecurityException(msg);
15421            }
15422
15423        // Special case for adding a package: by default turn on compatibility
15424        // mode.
15425        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15426            Uri data = intent.getData();
15427            String ssp;
15428            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15429                mCompatModePackages.handlePackageAddedLocked(ssp,
15430                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15431            }
15432        }
15433
15434        /*
15435         * If this is the time zone changed action, queue up a message that will reset the timezone
15436         * of all currently running processes. This message will get queued up before the broadcast
15437         * happens.
15438         */
15439        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15440            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15441        }
15442
15443        /*
15444         * If the user set the time, let all running processes know.
15445         */
15446        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15447            final int is24Hour = intent.getBooleanExtra(
15448                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15449            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15450            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15451            synchronized (stats) {
15452                stats.noteCurrentTimeChangedLocked();
15453            }
15454        }
15455
15456        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15457            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15458        }
15459
15460        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15461            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15462            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15463        }
15464
15465        // Add to the sticky list if requested.
15466        if (sticky) {
15467            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15468                    callingPid, callingUid)
15469                    != PackageManager.PERMISSION_GRANTED) {
15470                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15471                        + callingPid + ", uid=" + callingUid
15472                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15473                Slog.w(TAG, msg);
15474                throw new SecurityException(msg);
15475            }
15476            if (requiredPermission != null) {
15477                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15478                        + " and enforce permission " + requiredPermission);
15479                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15480            }
15481            if (intent.getComponent() != null) {
15482                throw new SecurityException(
15483                        "Sticky broadcasts can't target a specific component");
15484            }
15485            // We use userId directly here, since the "all" target is maintained
15486            // as a separate set of sticky broadcasts.
15487            if (userId != UserHandle.USER_ALL) {
15488                // But first, if this is not a broadcast to all users, then
15489                // make sure it doesn't conflict with an existing broadcast to
15490                // all users.
15491                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15492                        UserHandle.USER_ALL);
15493                if (stickies != null) {
15494                    ArrayList<Intent> list = stickies.get(intent.getAction());
15495                    if (list != null) {
15496                        int N = list.size();
15497                        int i;
15498                        for (i=0; i<N; i++) {
15499                            if (intent.filterEquals(list.get(i))) {
15500                                throw new IllegalArgumentException(
15501                                        "Sticky broadcast " + intent + " for user "
15502                                        + userId + " conflicts with existing global broadcast");
15503                            }
15504                        }
15505                    }
15506                }
15507            }
15508            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15509            if (stickies == null) {
15510                stickies = new ArrayMap<String, ArrayList<Intent>>();
15511                mStickyBroadcasts.put(userId, stickies);
15512            }
15513            ArrayList<Intent> list = stickies.get(intent.getAction());
15514            if (list == null) {
15515                list = new ArrayList<Intent>();
15516                stickies.put(intent.getAction(), list);
15517            }
15518            int N = list.size();
15519            int i;
15520            for (i=0; i<N; i++) {
15521                if (intent.filterEquals(list.get(i))) {
15522                    // This sticky already exists, replace it.
15523                    list.set(i, new Intent(intent));
15524                    break;
15525                }
15526            }
15527            if (i >= N) {
15528                list.add(new Intent(intent));
15529            }
15530        }
15531
15532        int[] users;
15533        if (userId == UserHandle.USER_ALL) {
15534            // Caller wants broadcast to go to all started users.
15535            users = mStartedUserArray;
15536        } else {
15537            // Caller wants broadcast to go to one specific user.
15538            users = new int[] {userId};
15539        }
15540
15541        // Figure out who all will receive this broadcast.
15542        List receivers = null;
15543        List<BroadcastFilter> registeredReceivers = null;
15544        // Need to resolve the intent to interested receivers...
15545        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15546                 == 0) {
15547            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15548        }
15549        if (intent.getComponent() == null) {
15550            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15551                // Query one target user at a time, excluding shell-restricted users
15552                UserManagerService ums = getUserManagerLocked();
15553                for (int i = 0; i < users.length; i++) {
15554                    if (ums.hasUserRestriction(
15555                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15556                        continue;
15557                    }
15558                    List<BroadcastFilter> registeredReceiversForUser =
15559                            mReceiverResolver.queryIntent(intent,
15560                                    resolvedType, false, users[i]);
15561                    if (registeredReceivers == null) {
15562                        registeredReceivers = registeredReceiversForUser;
15563                    } else if (registeredReceiversForUser != null) {
15564                        registeredReceivers.addAll(registeredReceiversForUser);
15565                    }
15566                }
15567            } else {
15568                registeredReceivers = mReceiverResolver.queryIntent(intent,
15569                        resolvedType, false, userId);
15570            }
15571        }
15572
15573        final boolean replacePending =
15574                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15575
15576        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15577                + " replacePending=" + replacePending);
15578
15579        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15580        if (!ordered && NR > 0) {
15581            // If we are not serializing this broadcast, then send the
15582            // registered receivers separately so they don't wait for the
15583            // components to be launched.
15584            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15585            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15586                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15587                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15588                    ordered, sticky, false, userId);
15589            if (DEBUG_BROADCAST) Slog.v(
15590                    TAG, "Enqueueing parallel broadcast " + r);
15591            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15592            if (!replaced) {
15593                queue.enqueueParallelBroadcastLocked(r);
15594                queue.scheduleBroadcastsLocked();
15595            }
15596            registeredReceivers = null;
15597            NR = 0;
15598        }
15599
15600        // Merge into one list.
15601        int ir = 0;
15602        if (receivers != null) {
15603            // A special case for PACKAGE_ADDED: do not allow the package
15604            // being added to see this broadcast.  This prevents them from
15605            // using this as a back door to get run as soon as they are
15606            // installed.  Maybe in the future we want to have a special install
15607            // broadcast or such for apps, but we'd like to deliberately make
15608            // this decision.
15609            String skipPackages[] = null;
15610            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15611                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15612                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15613                Uri data = intent.getData();
15614                if (data != null) {
15615                    String pkgName = data.getSchemeSpecificPart();
15616                    if (pkgName != null) {
15617                        skipPackages = new String[] { pkgName };
15618                    }
15619                }
15620            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15621                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15622            }
15623            if (skipPackages != null && (skipPackages.length > 0)) {
15624                for (String skipPackage : skipPackages) {
15625                    if (skipPackage != null) {
15626                        int NT = receivers.size();
15627                        for (int it=0; it<NT; it++) {
15628                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15629                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15630                                receivers.remove(it);
15631                                it--;
15632                                NT--;
15633                            }
15634                        }
15635                    }
15636                }
15637            }
15638
15639            int NT = receivers != null ? receivers.size() : 0;
15640            int it = 0;
15641            ResolveInfo curt = null;
15642            BroadcastFilter curr = null;
15643            while (it < NT && ir < NR) {
15644                if (curt == null) {
15645                    curt = (ResolveInfo)receivers.get(it);
15646                }
15647                if (curr == null) {
15648                    curr = registeredReceivers.get(ir);
15649                }
15650                if (curr.getPriority() >= curt.priority) {
15651                    // Insert this broadcast record into the final list.
15652                    receivers.add(it, curr);
15653                    ir++;
15654                    curr = null;
15655                    it++;
15656                    NT++;
15657                } else {
15658                    // Skip to the next ResolveInfo in the final list.
15659                    it++;
15660                    curt = null;
15661                }
15662            }
15663        }
15664        while (ir < NR) {
15665            if (receivers == null) {
15666                receivers = new ArrayList();
15667            }
15668            receivers.add(registeredReceivers.get(ir));
15669            ir++;
15670        }
15671
15672        if ((receivers != null && receivers.size() > 0)
15673                || resultTo != null) {
15674            BroadcastQueue queue = broadcastQueueForIntent(intent);
15675            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15676                    callerPackage, callingPid, callingUid, resolvedType,
15677                    requiredPermission, appOp, receivers, resultTo, resultCode,
15678                    resultData, map, ordered, sticky, false, userId);
15679            if (DEBUG_BROADCAST) Slog.v(
15680                    TAG, "Enqueueing ordered broadcast " + r
15681                    + ": prev had " + queue.mOrderedBroadcasts.size());
15682            if (DEBUG_BROADCAST) {
15683                int seq = r.intent.getIntExtra("seq", -1);
15684                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15685            }
15686            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15687            if (!replaced) {
15688                queue.enqueueOrderedBroadcastLocked(r);
15689                queue.scheduleBroadcastsLocked();
15690            }
15691        }
15692
15693        return ActivityManager.BROADCAST_SUCCESS;
15694    }
15695
15696    final Intent verifyBroadcastLocked(Intent intent) {
15697        // Refuse possible leaked file descriptors
15698        if (intent != null && intent.hasFileDescriptors() == true) {
15699            throw new IllegalArgumentException("File descriptors passed in Intent");
15700        }
15701
15702        int flags = intent.getFlags();
15703
15704        if (!mProcessesReady) {
15705            // if the caller really truly claims to know what they're doing, go
15706            // ahead and allow the broadcast without launching any receivers
15707            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15708                intent = new Intent(intent);
15709                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15710            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15711                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15712                        + " before boot completion");
15713                throw new IllegalStateException("Cannot broadcast before boot completed");
15714            }
15715        }
15716
15717        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15718            throw new IllegalArgumentException(
15719                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15720        }
15721
15722        return intent;
15723    }
15724
15725    public final int broadcastIntent(IApplicationThread caller,
15726            Intent intent, String resolvedType, IIntentReceiver resultTo,
15727            int resultCode, String resultData, Bundle map,
15728            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15729        enforceNotIsolatedCaller("broadcastIntent");
15730        synchronized(this) {
15731            intent = verifyBroadcastLocked(intent);
15732
15733            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15734            final int callingPid = Binder.getCallingPid();
15735            final int callingUid = Binder.getCallingUid();
15736            final long origId = Binder.clearCallingIdentity();
15737            int res = broadcastIntentLocked(callerApp,
15738                    callerApp != null ? callerApp.info.packageName : null,
15739                    intent, resolvedType, resultTo,
15740                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15741                    callingPid, callingUid, userId);
15742            Binder.restoreCallingIdentity(origId);
15743            return res;
15744        }
15745    }
15746
15747    int broadcastIntentInPackage(String packageName, int uid,
15748            Intent intent, String resolvedType, IIntentReceiver resultTo,
15749            int resultCode, String resultData, Bundle map,
15750            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15751        synchronized(this) {
15752            intent = verifyBroadcastLocked(intent);
15753
15754            final long origId = Binder.clearCallingIdentity();
15755            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15756                    resultTo, resultCode, resultData, map, requiredPermission,
15757                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15758            Binder.restoreCallingIdentity(origId);
15759            return res;
15760        }
15761    }
15762
15763    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15764        // Refuse possible leaked file descriptors
15765        if (intent != null && intent.hasFileDescriptors() == true) {
15766            throw new IllegalArgumentException("File descriptors passed in Intent");
15767        }
15768
15769        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15770                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15771
15772        synchronized(this) {
15773            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15774                    != PackageManager.PERMISSION_GRANTED) {
15775                String msg = "Permission Denial: unbroadcastIntent() from pid="
15776                        + Binder.getCallingPid()
15777                        + ", uid=" + Binder.getCallingUid()
15778                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15779                Slog.w(TAG, msg);
15780                throw new SecurityException(msg);
15781            }
15782            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15783            if (stickies != null) {
15784                ArrayList<Intent> list = stickies.get(intent.getAction());
15785                if (list != null) {
15786                    int N = list.size();
15787                    int i;
15788                    for (i=0; i<N; i++) {
15789                        if (intent.filterEquals(list.get(i))) {
15790                            list.remove(i);
15791                            break;
15792                        }
15793                    }
15794                    if (list.size() <= 0) {
15795                        stickies.remove(intent.getAction());
15796                    }
15797                }
15798                if (stickies.size() <= 0) {
15799                    mStickyBroadcasts.remove(userId);
15800                }
15801            }
15802        }
15803    }
15804
15805    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15806            String resultData, Bundle resultExtras, boolean resultAbort) {
15807        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15808        if (r == null) {
15809            Slog.w(TAG, "finishReceiver called but not found on queue");
15810            return false;
15811        }
15812
15813        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15814    }
15815
15816    void backgroundServicesFinishedLocked(int userId) {
15817        for (BroadcastQueue queue : mBroadcastQueues) {
15818            queue.backgroundServicesFinishedLocked(userId);
15819        }
15820    }
15821
15822    public void finishReceiver(IBinder who, int resultCode, String resultData,
15823            Bundle resultExtras, boolean resultAbort) {
15824        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15825
15826        // Refuse possible leaked file descriptors
15827        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15828            throw new IllegalArgumentException("File descriptors passed in Bundle");
15829        }
15830
15831        final long origId = Binder.clearCallingIdentity();
15832        try {
15833            boolean doNext = false;
15834            BroadcastRecord r;
15835
15836            synchronized(this) {
15837                r = broadcastRecordForReceiverLocked(who);
15838                if (r != null) {
15839                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15840                        resultData, resultExtras, resultAbort, true);
15841                }
15842            }
15843
15844            if (doNext) {
15845                r.queue.processNextBroadcast(false);
15846            }
15847            trimApplications();
15848        } finally {
15849            Binder.restoreCallingIdentity(origId);
15850        }
15851    }
15852
15853    // =========================================================
15854    // INSTRUMENTATION
15855    // =========================================================
15856
15857    public boolean startInstrumentation(ComponentName className,
15858            String profileFile, int flags, Bundle arguments,
15859            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15860            int userId, String abiOverride) {
15861        enforceNotIsolatedCaller("startInstrumentation");
15862        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15863                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15864        // Refuse possible leaked file descriptors
15865        if (arguments != null && arguments.hasFileDescriptors()) {
15866            throw new IllegalArgumentException("File descriptors passed in Bundle");
15867        }
15868
15869        synchronized(this) {
15870            InstrumentationInfo ii = null;
15871            ApplicationInfo ai = null;
15872            try {
15873                ii = mContext.getPackageManager().getInstrumentationInfo(
15874                    className, STOCK_PM_FLAGS);
15875                ai = AppGlobals.getPackageManager().getApplicationInfo(
15876                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15877            } catch (PackageManager.NameNotFoundException e) {
15878            } catch (RemoteException e) {
15879            }
15880            if (ii == null) {
15881                reportStartInstrumentationFailure(watcher, className,
15882                        "Unable to find instrumentation info for: " + className);
15883                return false;
15884            }
15885            if (ai == null) {
15886                reportStartInstrumentationFailure(watcher, className,
15887                        "Unable to find instrumentation target package: " + ii.targetPackage);
15888                return false;
15889            }
15890
15891            int match = mContext.getPackageManager().checkSignatures(
15892                    ii.targetPackage, ii.packageName);
15893            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15894                String msg = "Permission Denial: starting instrumentation "
15895                        + className + " from pid="
15896                        + Binder.getCallingPid()
15897                        + ", uid=" + Binder.getCallingPid()
15898                        + " not allowed because package " + ii.packageName
15899                        + " does not have a signature matching the target "
15900                        + ii.targetPackage;
15901                reportStartInstrumentationFailure(watcher, className, msg);
15902                throw new SecurityException(msg);
15903            }
15904
15905            final long origId = Binder.clearCallingIdentity();
15906            // Instrumentation can kill and relaunch even persistent processes
15907            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15908                    "start instr");
15909            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15910            app.instrumentationClass = className;
15911            app.instrumentationInfo = ai;
15912            app.instrumentationProfileFile = profileFile;
15913            app.instrumentationArguments = arguments;
15914            app.instrumentationWatcher = watcher;
15915            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15916            app.instrumentationResultClass = className;
15917            Binder.restoreCallingIdentity(origId);
15918        }
15919
15920        return true;
15921    }
15922
15923    /**
15924     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15925     * error to the logs, but if somebody is watching, send the report there too.  This enables
15926     * the "am" command to report errors with more information.
15927     *
15928     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15929     * @param cn The component name of the instrumentation.
15930     * @param report The error report.
15931     */
15932    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15933            ComponentName cn, String report) {
15934        Slog.w(TAG, report);
15935        try {
15936            if (watcher != null) {
15937                Bundle results = new Bundle();
15938                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15939                results.putString("Error", report);
15940                watcher.instrumentationStatus(cn, -1, results);
15941            }
15942        } catch (RemoteException e) {
15943            Slog.w(TAG, e);
15944        }
15945    }
15946
15947    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15948        if (app.instrumentationWatcher != null) {
15949            try {
15950                // NOTE:  IInstrumentationWatcher *must* be oneway here
15951                app.instrumentationWatcher.instrumentationFinished(
15952                    app.instrumentationClass,
15953                    resultCode,
15954                    results);
15955            } catch (RemoteException e) {
15956            }
15957        }
15958        if (app.instrumentationUiAutomationConnection != null) {
15959            try {
15960                app.instrumentationUiAutomationConnection.shutdown();
15961            } catch (RemoteException re) {
15962                /* ignore */
15963            }
15964            // Only a UiAutomation can set this flag and now that
15965            // it is finished we make sure it is reset to its default.
15966            mUserIsMonkey = false;
15967        }
15968        app.instrumentationWatcher = null;
15969        app.instrumentationUiAutomationConnection = null;
15970        app.instrumentationClass = null;
15971        app.instrumentationInfo = null;
15972        app.instrumentationProfileFile = null;
15973        app.instrumentationArguments = null;
15974
15975        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15976                "finished inst");
15977    }
15978
15979    public void finishInstrumentation(IApplicationThread target,
15980            int resultCode, Bundle results) {
15981        int userId = UserHandle.getCallingUserId();
15982        // Refuse possible leaked file descriptors
15983        if (results != null && results.hasFileDescriptors()) {
15984            throw new IllegalArgumentException("File descriptors passed in Intent");
15985        }
15986
15987        synchronized(this) {
15988            ProcessRecord app = getRecordForAppLocked(target);
15989            if (app == null) {
15990                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15991                return;
15992            }
15993            final long origId = Binder.clearCallingIdentity();
15994            finishInstrumentationLocked(app, resultCode, results);
15995            Binder.restoreCallingIdentity(origId);
15996        }
15997    }
15998
15999    // =========================================================
16000    // CONFIGURATION
16001    // =========================================================
16002
16003    public ConfigurationInfo getDeviceConfigurationInfo() {
16004        ConfigurationInfo config = new ConfigurationInfo();
16005        synchronized (this) {
16006            config.reqTouchScreen = mConfiguration.touchscreen;
16007            config.reqKeyboardType = mConfiguration.keyboard;
16008            config.reqNavigation = mConfiguration.navigation;
16009            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16010                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16011                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16012            }
16013            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16014                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16015                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16016            }
16017            config.reqGlEsVersion = GL_ES_VERSION;
16018        }
16019        return config;
16020    }
16021
16022    ActivityStack getFocusedStack() {
16023        return mStackSupervisor.getFocusedStack();
16024    }
16025
16026    public Configuration getConfiguration() {
16027        Configuration ci;
16028        synchronized(this) {
16029            ci = new Configuration(mConfiguration);
16030        }
16031        return ci;
16032    }
16033
16034    public void updatePersistentConfiguration(Configuration values) {
16035        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16036                "updateConfiguration()");
16037        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16038                "updateConfiguration()");
16039        if (values == null) {
16040            throw new NullPointerException("Configuration must not be null");
16041        }
16042
16043        synchronized(this) {
16044            final long origId = Binder.clearCallingIdentity();
16045            updateConfigurationLocked(values, null, true, false);
16046            Binder.restoreCallingIdentity(origId);
16047        }
16048    }
16049
16050    public void updateConfiguration(Configuration values) {
16051        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16052                "updateConfiguration()");
16053
16054        synchronized(this) {
16055            if (values == null && mWindowManager != null) {
16056                // sentinel: fetch the current configuration from the window manager
16057                values = mWindowManager.computeNewConfiguration();
16058            }
16059
16060            if (mWindowManager != null) {
16061                mProcessList.applyDisplaySize(mWindowManager);
16062            }
16063
16064            final long origId = Binder.clearCallingIdentity();
16065            if (values != null) {
16066                Settings.System.clearConfiguration(values);
16067            }
16068            updateConfigurationLocked(values, null, false, false);
16069            Binder.restoreCallingIdentity(origId);
16070        }
16071    }
16072
16073    /**
16074     * Do either or both things: (1) change the current configuration, and (2)
16075     * make sure the given activity is running with the (now) current
16076     * configuration.  Returns true if the activity has been left running, or
16077     * false if <var>starting</var> is being destroyed to match the new
16078     * configuration.
16079     * @param persistent TODO
16080     */
16081    boolean updateConfigurationLocked(Configuration values,
16082            ActivityRecord starting, boolean persistent, boolean initLocale) {
16083        int changes = 0;
16084
16085        if (values != null) {
16086            Configuration newConfig = new Configuration(mConfiguration);
16087            changes = newConfig.updateFrom(values);
16088            if (changes != 0) {
16089                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16090                    Slog.i(TAG, "Updating configuration to: " + values);
16091                }
16092
16093                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16094
16095                if (values.locale != null && !initLocale) {
16096                    saveLocaleLocked(values.locale,
16097                                     !values.locale.equals(mConfiguration.locale),
16098                                     values.userSetLocale);
16099                }
16100
16101                mConfigurationSeq++;
16102                if (mConfigurationSeq <= 0) {
16103                    mConfigurationSeq = 1;
16104                }
16105                newConfig.seq = mConfigurationSeq;
16106                mConfiguration = newConfig;
16107                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16108                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16109                //mUsageStatsService.noteStartConfig(newConfig);
16110
16111                final Configuration configCopy = new Configuration(mConfiguration);
16112
16113                // TODO: If our config changes, should we auto dismiss any currently
16114                // showing dialogs?
16115                mShowDialogs = shouldShowDialogs(newConfig);
16116
16117                AttributeCache ac = AttributeCache.instance();
16118                if (ac != null) {
16119                    ac.updateConfiguration(configCopy);
16120                }
16121
16122                // Make sure all resources in our process are updated
16123                // right now, so that anyone who is going to retrieve
16124                // resource values after we return will be sure to get
16125                // the new ones.  This is especially important during
16126                // boot, where the first config change needs to guarantee
16127                // all resources have that config before following boot
16128                // code is executed.
16129                mSystemThread.applyConfigurationToResources(configCopy);
16130
16131                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16132                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16133                    msg.obj = new Configuration(configCopy);
16134                    mHandler.sendMessage(msg);
16135                }
16136
16137                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16138                    ProcessRecord app = mLruProcesses.get(i);
16139                    try {
16140                        if (app.thread != null) {
16141                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16142                                    + app.processName + " new config " + mConfiguration);
16143                            app.thread.scheduleConfigurationChanged(configCopy);
16144                        }
16145                    } catch (Exception e) {
16146                    }
16147                }
16148                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16149                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16150                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16151                        | Intent.FLAG_RECEIVER_FOREGROUND);
16152                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16153                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16154                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16155                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16156                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16157                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16158                    broadcastIntentLocked(null, null, intent,
16159                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16160                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16161                }
16162            }
16163        }
16164
16165        boolean kept = true;
16166        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16167        // mainStack is null during startup.
16168        if (mainStack != null) {
16169            if (changes != 0 && starting == null) {
16170                // If the configuration changed, and the caller is not already
16171                // in the process of starting an activity, then find the top
16172                // activity to check if its configuration needs to change.
16173                starting = mainStack.topRunningActivityLocked(null);
16174            }
16175
16176            if (starting != null) {
16177                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16178                // And we need to make sure at this point that all other activities
16179                // are made visible with the correct configuration.
16180                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16181            }
16182        }
16183
16184        if (values != null && mWindowManager != null) {
16185            mWindowManager.setNewConfiguration(mConfiguration);
16186        }
16187
16188        return kept;
16189    }
16190
16191    /**
16192     * Decide based on the configuration whether we should shouw the ANR,
16193     * crash, etc dialogs.  The idea is that if there is no affordnace to
16194     * press the on-screen buttons, we shouldn't show the dialog.
16195     *
16196     * A thought: SystemUI might also want to get told about this, the Power
16197     * dialog / global actions also might want different behaviors.
16198     */
16199    private static final boolean shouldShowDialogs(Configuration config) {
16200        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16201                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16202    }
16203
16204    /**
16205     * Save the locale.  You must be inside a synchronized (this) block.
16206     */
16207    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16208        if(isDiff) {
16209            SystemProperties.set("user.language", l.getLanguage());
16210            SystemProperties.set("user.region", l.getCountry());
16211        }
16212
16213        if(isPersist) {
16214            SystemProperties.set("persist.sys.language", l.getLanguage());
16215            SystemProperties.set("persist.sys.country", l.getCountry());
16216            SystemProperties.set("persist.sys.localevar", l.getVariant());
16217        }
16218    }
16219
16220    @Override
16221    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16222        synchronized (this) {
16223            ActivityRecord srec = ActivityRecord.forToken(token);
16224            if (srec.task != null && srec.task.stack != null) {
16225                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16226            }
16227        }
16228        return false;
16229    }
16230
16231    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16232            Intent resultData) {
16233
16234        synchronized (this) {
16235            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16236            if (stack != null) {
16237                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16238            }
16239            return false;
16240        }
16241    }
16242
16243    public int getLaunchedFromUid(IBinder activityToken) {
16244        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16245        if (srec == null) {
16246            return -1;
16247        }
16248        return srec.launchedFromUid;
16249    }
16250
16251    public String getLaunchedFromPackage(IBinder activityToken) {
16252        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16253        if (srec == null) {
16254            return null;
16255        }
16256        return srec.launchedFromPackage;
16257    }
16258
16259    // =========================================================
16260    // LIFETIME MANAGEMENT
16261    // =========================================================
16262
16263    // Returns which broadcast queue the app is the current [or imminent] receiver
16264    // on, or 'null' if the app is not an active broadcast recipient.
16265    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16266        BroadcastRecord r = app.curReceiver;
16267        if (r != null) {
16268            return r.queue;
16269        }
16270
16271        // It's not the current receiver, but it might be starting up to become one
16272        synchronized (this) {
16273            for (BroadcastQueue queue : mBroadcastQueues) {
16274                r = queue.mPendingBroadcast;
16275                if (r != null && r.curApp == app) {
16276                    // found it; report which queue it's in
16277                    return queue;
16278                }
16279            }
16280        }
16281
16282        return null;
16283    }
16284
16285    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16286            boolean doingAll, long now) {
16287        if (mAdjSeq == app.adjSeq) {
16288            // This adjustment has already been computed.
16289            return app.curRawAdj;
16290        }
16291
16292        if (app.thread == null) {
16293            app.adjSeq = mAdjSeq;
16294            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16295            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16296            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16297        }
16298
16299        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16300        app.adjSource = null;
16301        app.adjTarget = null;
16302        app.empty = false;
16303        app.cached = false;
16304
16305        final int activitiesSize = app.activities.size();
16306
16307        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16308            // The max adjustment doesn't allow this app to be anything
16309            // below foreground, so it is not worth doing work for it.
16310            app.adjType = "fixed";
16311            app.adjSeq = mAdjSeq;
16312            app.curRawAdj = app.maxAdj;
16313            app.foregroundActivities = false;
16314            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16315            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16316            // System processes can do UI, and when they do we want to have
16317            // them trim their memory after the user leaves the UI.  To
16318            // facilitate this, here we need to determine whether or not it
16319            // is currently showing UI.
16320            app.systemNoUi = true;
16321            if (app == TOP_APP) {
16322                app.systemNoUi = false;
16323            } else if (activitiesSize > 0) {
16324                for (int j = 0; j < activitiesSize; j++) {
16325                    final ActivityRecord r = app.activities.get(j);
16326                    if (r.visible) {
16327                        app.systemNoUi = false;
16328                    }
16329                }
16330            }
16331            if (!app.systemNoUi) {
16332                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16333            }
16334            return (app.curAdj=app.maxAdj);
16335        }
16336
16337        app.systemNoUi = false;
16338
16339        // Determine the importance of the process, starting with most
16340        // important to least, and assign an appropriate OOM adjustment.
16341        int adj;
16342        int schedGroup;
16343        int procState;
16344        boolean foregroundActivities = false;
16345        BroadcastQueue queue;
16346        if (app == TOP_APP) {
16347            // The last app on the list is the foreground app.
16348            adj = ProcessList.FOREGROUND_APP_ADJ;
16349            schedGroup = Process.THREAD_GROUP_DEFAULT;
16350            app.adjType = "top-activity";
16351            foregroundActivities = true;
16352            procState = ActivityManager.PROCESS_STATE_TOP;
16353        } else if (app.instrumentationClass != null) {
16354            // Don't want to kill running instrumentation.
16355            adj = ProcessList.FOREGROUND_APP_ADJ;
16356            schedGroup = Process.THREAD_GROUP_DEFAULT;
16357            app.adjType = "instrumentation";
16358            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16359        } else if ((queue = isReceivingBroadcast(app)) != null) {
16360            // An app that is currently receiving a broadcast also
16361            // counts as being in the foreground for OOM killer purposes.
16362            // It's placed in a sched group based on the nature of the
16363            // broadcast as reflected by which queue it's active in.
16364            adj = ProcessList.FOREGROUND_APP_ADJ;
16365            schedGroup = (queue == mFgBroadcastQueue)
16366                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16367            app.adjType = "broadcast";
16368            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16369        } else if (app.executingServices.size() > 0) {
16370            // An app that is currently executing a service callback also
16371            // counts as being in the foreground.
16372            adj = ProcessList.FOREGROUND_APP_ADJ;
16373            schedGroup = app.execServicesFg ?
16374                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16375            app.adjType = "exec-service";
16376            procState = ActivityManager.PROCESS_STATE_SERVICE;
16377            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16378        } else {
16379            // As far as we know the process is empty.  We may change our mind later.
16380            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16381            // At this point we don't actually know the adjustment.  Use the cached adj
16382            // value that the caller wants us to.
16383            adj = cachedAdj;
16384            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16385            app.cached = true;
16386            app.empty = true;
16387            app.adjType = "cch-empty";
16388        }
16389
16390        // Examine all activities if not already foreground.
16391        if (!foregroundActivities && activitiesSize > 0) {
16392            for (int j = 0; j < activitiesSize; j++) {
16393                final ActivityRecord r = app.activities.get(j);
16394                if (r.app != app) {
16395                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16396                            + app + "?!?");
16397                    continue;
16398                }
16399                if (r.visible) {
16400                    // App has a visible activity; only upgrade adjustment.
16401                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16402                        adj = ProcessList.VISIBLE_APP_ADJ;
16403                        app.adjType = "visible";
16404                    }
16405                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16406                        procState = ActivityManager.PROCESS_STATE_TOP;
16407                    }
16408                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16409                    app.cached = false;
16410                    app.empty = false;
16411                    foregroundActivities = true;
16412                    break;
16413                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16414                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16415                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16416                        app.adjType = "pausing";
16417                    }
16418                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16419                        procState = ActivityManager.PROCESS_STATE_TOP;
16420                    }
16421                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16422                    app.cached = false;
16423                    app.empty = false;
16424                    foregroundActivities = true;
16425                } else if (r.state == ActivityState.STOPPING) {
16426                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16427                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16428                        app.adjType = "stopping";
16429                    }
16430                    // For the process state, we will at this point consider the
16431                    // process to be cached.  It will be cached either as an activity
16432                    // or empty depending on whether the activity is finishing.  We do
16433                    // this so that we can treat the process as cached for purposes of
16434                    // memory trimming (determing current memory level, trim command to
16435                    // send to process) since there can be an arbitrary number of stopping
16436                    // processes and they should soon all go into the cached state.
16437                    if (!r.finishing) {
16438                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16439                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16440                        }
16441                    }
16442                    app.cached = false;
16443                    app.empty = false;
16444                    foregroundActivities = true;
16445                } else {
16446                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16447                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16448                        app.adjType = "cch-act";
16449                    }
16450                }
16451            }
16452        }
16453
16454        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16455            if (app.foregroundServices) {
16456                // The user is aware of this app, so make it visible.
16457                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16458                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16459                app.cached = false;
16460                app.adjType = "fg-service";
16461                schedGroup = Process.THREAD_GROUP_DEFAULT;
16462            } else if (app.forcingToForeground != null) {
16463                // The user is aware of this app, so make it visible.
16464                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16465                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16466                app.cached = false;
16467                app.adjType = "force-fg";
16468                app.adjSource = app.forcingToForeground;
16469                schedGroup = Process.THREAD_GROUP_DEFAULT;
16470            }
16471        }
16472
16473        if (app == mHeavyWeightProcess) {
16474            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16475                // We don't want to kill the current heavy-weight process.
16476                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16477                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16478                app.cached = false;
16479                app.adjType = "heavy";
16480            }
16481            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16482                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16483            }
16484        }
16485
16486        if (app == mHomeProcess) {
16487            if (adj > ProcessList.HOME_APP_ADJ) {
16488                // This process is hosting what we currently consider to be the
16489                // home app, so we don't want to let it go into the background.
16490                adj = ProcessList.HOME_APP_ADJ;
16491                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16492                app.cached = false;
16493                app.adjType = "home";
16494            }
16495            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16496                procState = ActivityManager.PROCESS_STATE_HOME;
16497            }
16498        }
16499
16500        if (app == mPreviousProcess && app.activities.size() > 0) {
16501            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16502                // This was the previous process that showed UI to the user.
16503                // We want to try to keep it around more aggressively, to give
16504                // a good experience around switching between two apps.
16505                adj = ProcessList.PREVIOUS_APP_ADJ;
16506                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16507                app.cached = false;
16508                app.adjType = "previous";
16509            }
16510            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16511                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16512            }
16513        }
16514
16515        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16516                + " reason=" + app.adjType);
16517
16518        // By default, we use the computed adjustment.  It may be changed if
16519        // there are applications dependent on our services or providers, but
16520        // this gives us a baseline and makes sure we don't get into an
16521        // infinite recursion.
16522        app.adjSeq = mAdjSeq;
16523        app.curRawAdj = adj;
16524        app.hasStartedServices = false;
16525
16526        if (mBackupTarget != null && app == mBackupTarget.app) {
16527            // If possible we want to avoid killing apps while they're being backed up
16528            if (adj > ProcessList.BACKUP_APP_ADJ) {
16529                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16530                adj = ProcessList.BACKUP_APP_ADJ;
16531                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16532                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16533                }
16534                app.adjType = "backup";
16535                app.cached = false;
16536            }
16537            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16538                procState = ActivityManager.PROCESS_STATE_BACKUP;
16539            }
16540        }
16541
16542        boolean mayBeTop = false;
16543
16544        for (int is = app.services.size()-1;
16545                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16546                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16547                        || procState > ActivityManager.PROCESS_STATE_TOP);
16548                is--) {
16549            ServiceRecord s = app.services.valueAt(is);
16550            if (s.startRequested) {
16551                app.hasStartedServices = true;
16552                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16553                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16554                }
16555                if (app.hasShownUi && app != mHomeProcess) {
16556                    // If this process has shown some UI, let it immediately
16557                    // go to the LRU list because it may be pretty heavy with
16558                    // UI stuff.  We'll tag it with a label just to help
16559                    // debug and understand what is going on.
16560                    if (adj > ProcessList.SERVICE_ADJ) {
16561                        app.adjType = "cch-started-ui-services";
16562                    }
16563                } else {
16564                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16565                        // This service has seen some activity within
16566                        // recent memory, so we will keep its process ahead
16567                        // of the background processes.
16568                        if (adj > ProcessList.SERVICE_ADJ) {
16569                            adj = ProcessList.SERVICE_ADJ;
16570                            app.adjType = "started-services";
16571                            app.cached = false;
16572                        }
16573                    }
16574                    // If we have let the service slide into the background
16575                    // state, still have some text describing what it is doing
16576                    // even though the service no longer has an impact.
16577                    if (adj > ProcessList.SERVICE_ADJ) {
16578                        app.adjType = "cch-started-services";
16579                    }
16580                }
16581            }
16582            for (int conni = s.connections.size()-1;
16583                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16584                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16585                            || procState > ActivityManager.PROCESS_STATE_TOP);
16586                    conni--) {
16587                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16588                for (int i = 0;
16589                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16590                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16591                                || procState > ActivityManager.PROCESS_STATE_TOP);
16592                        i++) {
16593                    // XXX should compute this based on the max of
16594                    // all connected clients.
16595                    ConnectionRecord cr = clist.get(i);
16596                    if (cr.binding.client == app) {
16597                        // Binding to ourself is not interesting.
16598                        continue;
16599                    }
16600                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16601                        ProcessRecord client = cr.binding.client;
16602                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16603                                TOP_APP, doingAll, now);
16604                        int clientProcState = client.curProcState;
16605                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16606                            // If the other app is cached for any reason, for purposes here
16607                            // we are going to consider it empty.  The specific cached state
16608                            // doesn't propagate except under certain conditions.
16609                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16610                        }
16611                        String adjType = null;
16612                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16613                            // Not doing bind OOM management, so treat
16614                            // this guy more like a started service.
16615                            if (app.hasShownUi && app != mHomeProcess) {
16616                                // If this process has shown some UI, let it immediately
16617                                // go to the LRU list because it may be pretty heavy with
16618                                // UI stuff.  We'll tag it with a label just to help
16619                                // debug and understand what is going on.
16620                                if (adj > clientAdj) {
16621                                    adjType = "cch-bound-ui-services";
16622                                }
16623                                app.cached = false;
16624                                clientAdj = adj;
16625                                clientProcState = procState;
16626                            } else {
16627                                if (now >= (s.lastActivity
16628                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16629                                    // This service has not seen activity within
16630                                    // recent memory, so allow it to drop to the
16631                                    // LRU list if there is no other reason to keep
16632                                    // it around.  We'll also tag it with a label just
16633                                    // to help debug and undertand what is going on.
16634                                    if (adj > clientAdj) {
16635                                        adjType = "cch-bound-services";
16636                                    }
16637                                    clientAdj = adj;
16638                                }
16639                            }
16640                        }
16641                        if (adj > clientAdj) {
16642                            // If this process has recently shown UI, and
16643                            // the process that is binding to it is less
16644                            // important than being visible, then we don't
16645                            // care about the binding as much as we care
16646                            // about letting this process get into the LRU
16647                            // list to be killed and restarted if needed for
16648                            // memory.
16649                            if (app.hasShownUi && app != mHomeProcess
16650                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16651                                adjType = "cch-bound-ui-services";
16652                            } else {
16653                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16654                                        |Context.BIND_IMPORTANT)) != 0) {
16655                                    adj = clientAdj;
16656                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16657                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16658                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16659                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16660                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16661                                    adj = clientAdj;
16662                                } else {
16663                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16664                                        adj = ProcessList.VISIBLE_APP_ADJ;
16665                                    }
16666                                }
16667                                if (!client.cached) {
16668                                    app.cached = false;
16669                                }
16670                                adjType = "service";
16671                            }
16672                        }
16673                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16674                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16675                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16676                            }
16677                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16678                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16679                                    // Special handling of clients who are in the top state.
16680                                    // We *may* want to consider this process to be in the
16681                                    // top state as well, but only if there is not another
16682                                    // reason for it to be running.  Being on the top is a
16683                                    // special state, meaning you are specifically running
16684                                    // for the current top app.  If the process is already
16685                                    // running in the background for some other reason, it
16686                                    // is more important to continue considering it to be
16687                                    // in the background state.
16688                                    mayBeTop = true;
16689                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16690                                } else {
16691                                    // Special handling for above-top states (persistent
16692                                    // processes).  These should not bring the current process
16693                                    // into the top state, since they are not on top.  Instead
16694                                    // give them the best state after that.
16695                                    clientProcState =
16696                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16697                                }
16698                            }
16699                        } else {
16700                            if (clientProcState <
16701                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16702                                clientProcState =
16703                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16704                            }
16705                        }
16706                        if (procState > clientProcState) {
16707                            procState = clientProcState;
16708                        }
16709                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16710                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16711                            app.pendingUiClean = true;
16712                        }
16713                        if (adjType != null) {
16714                            app.adjType = adjType;
16715                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16716                                    .REASON_SERVICE_IN_USE;
16717                            app.adjSource = cr.binding.client;
16718                            app.adjSourceProcState = clientProcState;
16719                            app.adjTarget = s.name;
16720                        }
16721                    }
16722                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16723                        app.treatLikeActivity = true;
16724                    }
16725                    final ActivityRecord a = cr.activity;
16726                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16727                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16728                                (a.visible || a.state == ActivityState.RESUMED
16729                                 || a.state == ActivityState.PAUSING)) {
16730                            adj = ProcessList.FOREGROUND_APP_ADJ;
16731                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16732                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16733                            }
16734                            app.cached = false;
16735                            app.adjType = "service";
16736                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16737                                    .REASON_SERVICE_IN_USE;
16738                            app.adjSource = a;
16739                            app.adjSourceProcState = procState;
16740                            app.adjTarget = s.name;
16741                        }
16742                    }
16743                }
16744            }
16745        }
16746
16747        for (int provi = app.pubProviders.size()-1;
16748                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16749                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16750                        || procState > ActivityManager.PROCESS_STATE_TOP);
16751                provi--) {
16752            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16753            for (int i = cpr.connections.size()-1;
16754                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16755                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16756                            || procState > ActivityManager.PROCESS_STATE_TOP);
16757                    i--) {
16758                ContentProviderConnection conn = cpr.connections.get(i);
16759                ProcessRecord client = conn.client;
16760                if (client == app) {
16761                    // Being our own client is not interesting.
16762                    continue;
16763                }
16764                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16765                int clientProcState = client.curProcState;
16766                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16767                    // If the other app is cached for any reason, for purposes here
16768                    // we are going to consider it empty.
16769                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16770                }
16771                if (adj > clientAdj) {
16772                    if (app.hasShownUi && app != mHomeProcess
16773                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16774                        app.adjType = "cch-ui-provider";
16775                    } else {
16776                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16777                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16778                        app.adjType = "provider";
16779                    }
16780                    app.cached &= client.cached;
16781                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16782                            .REASON_PROVIDER_IN_USE;
16783                    app.adjSource = client;
16784                    app.adjSourceProcState = clientProcState;
16785                    app.adjTarget = cpr.name;
16786                }
16787                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16788                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16789                        // Special handling of clients who are in the top state.
16790                        // We *may* want to consider this process to be in the
16791                        // top state as well, but only if there is not another
16792                        // reason for it to be running.  Being on the top is a
16793                        // special state, meaning you are specifically running
16794                        // for the current top app.  If the process is already
16795                        // running in the background for some other reason, it
16796                        // is more important to continue considering it to be
16797                        // in the background state.
16798                        mayBeTop = true;
16799                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16800                    } else {
16801                        // Special handling for above-top states (persistent
16802                        // processes).  These should not bring the current process
16803                        // into the top state, since they are not on top.  Instead
16804                        // give them the best state after that.
16805                        clientProcState =
16806                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16807                    }
16808                }
16809                if (procState > clientProcState) {
16810                    procState = clientProcState;
16811                }
16812                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16813                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16814                }
16815            }
16816            // If the provider has external (non-framework) process
16817            // dependencies, ensure that its adjustment is at least
16818            // FOREGROUND_APP_ADJ.
16819            if (cpr.hasExternalProcessHandles()) {
16820                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16821                    adj = ProcessList.FOREGROUND_APP_ADJ;
16822                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16823                    app.cached = false;
16824                    app.adjType = "provider";
16825                    app.adjTarget = cpr.name;
16826                }
16827                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16828                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16829                }
16830            }
16831        }
16832
16833        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16834            // A client of one of our services or providers is in the top state.  We
16835            // *may* want to be in the top state, but not if we are already running in
16836            // the background for some other reason.  For the decision here, we are going
16837            // to pick out a few specific states that we want to remain in when a client
16838            // is top (states that tend to be longer-term) and otherwise allow it to go
16839            // to the top state.
16840            switch (procState) {
16841                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16842                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16843                case ActivityManager.PROCESS_STATE_SERVICE:
16844                    // These all are longer-term states, so pull them up to the top
16845                    // of the background states, but not all the way to the top state.
16846                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16847                    break;
16848                default:
16849                    // Otherwise, top is a better choice, so take it.
16850                    procState = ActivityManager.PROCESS_STATE_TOP;
16851                    break;
16852            }
16853        }
16854
16855        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16856            if (app.hasClientActivities) {
16857                // This is a cached process, but with client activities.  Mark it so.
16858                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16859                app.adjType = "cch-client-act";
16860            } else if (app.treatLikeActivity) {
16861                // This is a cached process, but somebody wants us to treat it like it has
16862                // an activity, okay!
16863                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16864                app.adjType = "cch-as-act";
16865            }
16866        }
16867
16868        if (adj == ProcessList.SERVICE_ADJ) {
16869            if (doingAll) {
16870                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16871                mNewNumServiceProcs++;
16872                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16873                if (!app.serviceb) {
16874                    // This service isn't far enough down on the LRU list to
16875                    // normally be a B service, but if we are low on RAM and it
16876                    // is large we want to force it down since we would prefer to
16877                    // keep launcher over it.
16878                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16879                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16880                        app.serviceHighRam = true;
16881                        app.serviceb = true;
16882                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16883                    } else {
16884                        mNewNumAServiceProcs++;
16885                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16886                    }
16887                } else {
16888                    app.serviceHighRam = false;
16889                }
16890            }
16891            if (app.serviceb) {
16892                adj = ProcessList.SERVICE_B_ADJ;
16893            }
16894        }
16895
16896        app.curRawAdj = adj;
16897
16898        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16899        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16900        if (adj > app.maxAdj) {
16901            adj = app.maxAdj;
16902            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16903                schedGroup = Process.THREAD_GROUP_DEFAULT;
16904            }
16905        }
16906
16907        // Do final modification to adj.  Everything we do between here and applying
16908        // the final setAdj must be done in this function, because we will also use
16909        // it when computing the final cached adj later.  Note that we don't need to
16910        // worry about this for max adj above, since max adj will always be used to
16911        // keep it out of the cached vaues.
16912        app.curAdj = app.modifyRawOomAdj(adj);
16913        app.curSchedGroup = schedGroup;
16914        app.curProcState = procState;
16915        app.foregroundActivities = foregroundActivities;
16916
16917        return app.curRawAdj;
16918    }
16919
16920    /**
16921     * Schedule PSS collection of a process.
16922     */
16923    void requestPssLocked(ProcessRecord proc, int procState) {
16924        if (mPendingPssProcesses.contains(proc)) {
16925            return;
16926        }
16927        if (mPendingPssProcesses.size() == 0) {
16928            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16929        }
16930        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16931        proc.pssProcState = procState;
16932        mPendingPssProcesses.add(proc);
16933    }
16934
16935    /**
16936     * Schedule PSS collection of all processes.
16937     */
16938    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16939        if (!always) {
16940            if (now < (mLastFullPssTime +
16941                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16942                return;
16943            }
16944        }
16945        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16946        mLastFullPssTime = now;
16947        mFullPssPending = true;
16948        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16949        mPendingPssProcesses.clear();
16950        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16951            ProcessRecord app = mLruProcesses.get(i);
16952            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16953                app.pssProcState = app.setProcState;
16954                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16955                        isSleeping(), now);
16956                mPendingPssProcesses.add(app);
16957            }
16958        }
16959        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16960    }
16961
16962    /**
16963     * Ask a given process to GC right now.
16964     */
16965    final void performAppGcLocked(ProcessRecord app) {
16966        try {
16967            app.lastRequestedGc = SystemClock.uptimeMillis();
16968            if (app.thread != null) {
16969                if (app.reportLowMemory) {
16970                    app.reportLowMemory = false;
16971                    app.thread.scheduleLowMemory();
16972                } else {
16973                    app.thread.processInBackground();
16974                }
16975            }
16976        } catch (Exception e) {
16977            // whatever.
16978        }
16979    }
16980
16981    /**
16982     * Returns true if things are idle enough to perform GCs.
16983     */
16984    private final boolean canGcNowLocked() {
16985        boolean processingBroadcasts = false;
16986        for (BroadcastQueue q : mBroadcastQueues) {
16987            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16988                processingBroadcasts = true;
16989            }
16990        }
16991        return !processingBroadcasts
16992                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16993    }
16994
16995    /**
16996     * Perform GCs on all processes that are waiting for it, but only
16997     * if things are idle.
16998     */
16999    final void performAppGcsLocked() {
17000        final int N = mProcessesToGc.size();
17001        if (N <= 0) {
17002            return;
17003        }
17004        if (canGcNowLocked()) {
17005            while (mProcessesToGc.size() > 0) {
17006                ProcessRecord proc = mProcessesToGc.remove(0);
17007                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17008                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17009                            <= SystemClock.uptimeMillis()) {
17010                        // To avoid spamming the system, we will GC processes one
17011                        // at a time, waiting a few seconds between each.
17012                        performAppGcLocked(proc);
17013                        scheduleAppGcsLocked();
17014                        return;
17015                    } else {
17016                        // It hasn't been long enough since we last GCed this
17017                        // process...  put it in the list to wait for its time.
17018                        addProcessToGcListLocked(proc);
17019                        break;
17020                    }
17021                }
17022            }
17023
17024            scheduleAppGcsLocked();
17025        }
17026    }
17027
17028    /**
17029     * If all looks good, perform GCs on all processes waiting for them.
17030     */
17031    final void performAppGcsIfAppropriateLocked() {
17032        if (canGcNowLocked()) {
17033            performAppGcsLocked();
17034            return;
17035        }
17036        // Still not idle, wait some more.
17037        scheduleAppGcsLocked();
17038    }
17039
17040    /**
17041     * Schedule the execution of all pending app GCs.
17042     */
17043    final void scheduleAppGcsLocked() {
17044        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17045
17046        if (mProcessesToGc.size() > 0) {
17047            // Schedule a GC for the time to the next process.
17048            ProcessRecord proc = mProcessesToGc.get(0);
17049            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17050
17051            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17052            long now = SystemClock.uptimeMillis();
17053            if (when < (now+GC_TIMEOUT)) {
17054                when = now + GC_TIMEOUT;
17055            }
17056            mHandler.sendMessageAtTime(msg, when);
17057        }
17058    }
17059
17060    /**
17061     * Add a process to the array of processes waiting to be GCed.  Keeps the
17062     * list in sorted order by the last GC time.  The process can't already be
17063     * on the list.
17064     */
17065    final void addProcessToGcListLocked(ProcessRecord proc) {
17066        boolean added = false;
17067        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17068            if (mProcessesToGc.get(i).lastRequestedGc <
17069                    proc.lastRequestedGc) {
17070                added = true;
17071                mProcessesToGc.add(i+1, proc);
17072                break;
17073            }
17074        }
17075        if (!added) {
17076            mProcessesToGc.add(0, proc);
17077        }
17078    }
17079
17080    /**
17081     * Set up to ask a process to GC itself.  This will either do it
17082     * immediately, or put it on the list of processes to gc the next
17083     * time things are idle.
17084     */
17085    final void scheduleAppGcLocked(ProcessRecord app) {
17086        long now = SystemClock.uptimeMillis();
17087        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17088            return;
17089        }
17090        if (!mProcessesToGc.contains(app)) {
17091            addProcessToGcListLocked(app);
17092            scheduleAppGcsLocked();
17093        }
17094    }
17095
17096    final void checkExcessivePowerUsageLocked(boolean doKills) {
17097        updateCpuStatsNow();
17098
17099        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17100        boolean doWakeKills = doKills;
17101        boolean doCpuKills = doKills;
17102        if (mLastPowerCheckRealtime == 0) {
17103            doWakeKills = false;
17104        }
17105        if (mLastPowerCheckUptime == 0) {
17106            doCpuKills = false;
17107        }
17108        if (stats.isScreenOn()) {
17109            doWakeKills = false;
17110        }
17111        final long curRealtime = SystemClock.elapsedRealtime();
17112        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17113        final long curUptime = SystemClock.uptimeMillis();
17114        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17115        mLastPowerCheckRealtime = curRealtime;
17116        mLastPowerCheckUptime = curUptime;
17117        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17118            doWakeKills = false;
17119        }
17120        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17121            doCpuKills = false;
17122        }
17123        int i = mLruProcesses.size();
17124        while (i > 0) {
17125            i--;
17126            ProcessRecord app = mLruProcesses.get(i);
17127            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17128                long wtime;
17129                synchronized (stats) {
17130                    wtime = stats.getProcessWakeTime(app.info.uid,
17131                            app.pid, curRealtime);
17132                }
17133                long wtimeUsed = wtime - app.lastWakeTime;
17134                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17135                if (DEBUG_POWER) {
17136                    StringBuilder sb = new StringBuilder(128);
17137                    sb.append("Wake for ");
17138                    app.toShortString(sb);
17139                    sb.append(": over ");
17140                    TimeUtils.formatDuration(realtimeSince, sb);
17141                    sb.append(" used ");
17142                    TimeUtils.formatDuration(wtimeUsed, sb);
17143                    sb.append(" (");
17144                    sb.append((wtimeUsed*100)/realtimeSince);
17145                    sb.append("%)");
17146                    Slog.i(TAG, sb.toString());
17147                    sb.setLength(0);
17148                    sb.append("CPU for ");
17149                    app.toShortString(sb);
17150                    sb.append(": over ");
17151                    TimeUtils.formatDuration(uptimeSince, sb);
17152                    sb.append(" used ");
17153                    TimeUtils.formatDuration(cputimeUsed, sb);
17154                    sb.append(" (");
17155                    sb.append((cputimeUsed*100)/uptimeSince);
17156                    sb.append("%)");
17157                    Slog.i(TAG, sb.toString());
17158                }
17159                // If a process has held a wake lock for more
17160                // than 50% of the time during this period,
17161                // that sounds bad.  Kill!
17162                if (doWakeKills && realtimeSince > 0
17163                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17164                    synchronized (stats) {
17165                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17166                                realtimeSince, wtimeUsed);
17167                    }
17168                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17169                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17170                } else if (doCpuKills && uptimeSince > 0
17171                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17172                    synchronized (stats) {
17173                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17174                                uptimeSince, cputimeUsed);
17175                    }
17176                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17177                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17178                } else {
17179                    app.lastWakeTime = wtime;
17180                    app.lastCpuTime = app.curCpuTime;
17181                }
17182            }
17183        }
17184    }
17185
17186    private final boolean applyOomAdjLocked(ProcessRecord app,
17187            ProcessRecord TOP_APP, boolean doingAll, long now) {
17188        boolean success = true;
17189
17190        if (app.curRawAdj != app.setRawAdj) {
17191            app.setRawAdj = app.curRawAdj;
17192        }
17193
17194        int changes = 0;
17195
17196        if (app.curAdj != app.setAdj) {
17197            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17198            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17199                TAG, "Set " + app.pid + " " + app.processName +
17200                " adj " + app.curAdj + ": " + app.adjType);
17201            app.setAdj = app.curAdj;
17202        }
17203
17204        if (app.setSchedGroup != app.curSchedGroup) {
17205            app.setSchedGroup = app.curSchedGroup;
17206            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17207                    "Setting process group of " + app.processName
17208                    + " to " + app.curSchedGroup);
17209            if (app.waitingToKill != null &&
17210                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17211                app.kill(app.waitingToKill, true);
17212                success = false;
17213            } else {
17214                if (true) {
17215                    long oldId = Binder.clearCallingIdentity();
17216                    try {
17217                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17218                    } catch (Exception e) {
17219                        Slog.w(TAG, "Failed setting process group of " + app.pid
17220                                + " to " + app.curSchedGroup);
17221                        e.printStackTrace();
17222                    } finally {
17223                        Binder.restoreCallingIdentity(oldId);
17224                    }
17225                } else {
17226                    if (app.thread != null) {
17227                        try {
17228                            app.thread.setSchedulingGroup(app.curSchedGroup);
17229                        } catch (RemoteException e) {
17230                        }
17231                    }
17232                }
17233                Process.setSwappiness(app.pid,
17234                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17235            }
17236        }
17237        if (app.repForegroundActivities != app.foregroundActivities) {
17238            app.repForegroundActivities = app.foregroundActivities;
17239            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17240        }
17241        if (app.repProcState != app.curProcState) {
17242            app.repProcState = app.curProcState;
17243            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17244            if (app.thread != null) {
17245                try {
17246                    if (false) {
17247                        //RuntimeException h = new RuntimeException("here");
17248                        Slog.i(TAG, "Sending new process state " + app.repProcState
17249                                + " to " + app /*, h*/);
17250                    }
17251                    app.thread.setProcessState(app.repProcState);
17252                } catch (RemoteException e) {
17253                }
17254            }
17255        }
17256        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17257                app.setProcState)) {
17258            app.lastStateTime = now;
17259            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17260                    isSleeping(), now);
17261            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17262                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17263                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17264                    + (app.nextPssTime-now) + ": " + app);
17265        } else {
17266            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17267                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17268                requestPssLocked(app, app.setProcState);
17269                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17270                        isSleeping(), now);
17271            } else if (false && DEBUG_PSS) {
17272                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17273            }
17274        }
17275        if (app.setProcState != app.curProcState) {
17276            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17277                    "Proc state change of " + app.processName
17278                    + " to " + app.curProcState);
17279            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17280            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17281            if (setImportant && !curImportant) {
17282                // This app is no longer something we consider important enough to allow to
17283                // use arbitrary amounts of battery power.  Note
17284                // its current wake lock time to later know to kill it if
17285                // it is not behaving well.
17286                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17287                synchronized (stats) {
17288                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17289                            app.pid, SystemClock.elapsedRealtime());
17290                }
17291                app.lastCpuTime = app.curCpuTime;
17292
17293            }
17294            app.setProcState = app.curProcState;
17295            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17296                app.notCachedSinceIdle = false;
17297            }
17298            if (!doingAll) {
17299                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17300            } else {
17301                app.procStateChanged = true;
17302            }
17303        }
17304
17305        if (changes != 0) {
17306            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17307            int i = mPendingProcessChanges.size()-1;
17308            ProcessChangeItem item = null;
17309            while (i >= 0) {
17310                item = mPendingProcessChanges.get(i);
17311                if (item.pid == app.pid) {
17312                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17313                    break;
17314                }
17315                i--;
17316            }
17317            if (i < 0) {
17318                // No existing item in pending changes; need a new one.
17319                final int NA = mAvailProcessChanges.size();
17320                if (NA > 0) {
17321                    item = mAvailProcessChanges.remove(NA-1);
17322                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17323                } else {
17324                    item = new ProcessChangeItem();
17325                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17326                }
17327                item.changes = 0;
17328                item.pid = app.pid;
17329                item.uid = app.info.uid;
17330                if (mPendingProcessChanges.size() == 0) {
17331                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17332                            "*** Enqueueing dispatch processes changed!");
17333                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17334                }
17335                mPendingProcessChanges.add(item);
17336            }
17337            item.changes |= changes;
17338            item.processState = app.repProcState;
17339            item.foregroundActivities = app.repForegroundActivities;
17340            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17341                    + Integer.toHexString(System.identityHashCode(item))
17342                    + " " + app.toShortString() + ": changes=" + item.changes
17343                    + " procState=" + item.processState
17344                    + " foreground=" + item.foregroundActivities
17345                    + " type=" + app.adjType + " source=" + app.adjSource
17346                    + " target=" + app.adjTarget);
17347        }
17348
17349        return success;
17350    }
17351
17352    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17353        if (proc.thread != null) {
17354            if (proc.baseProcessTracker != null) {
17355                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17356            }
17357            if (proc.repProcState >= 0) {
17358                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17359                        proc.repProcState);
17360            }
17361        }
17362    }
17363
17364    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17365            ProcessRecord TOP_APP, boolean doingAll, long now) {
17366        if (app.thread == null) {
17367            return false;
17368        }
17369
17370        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17371
17372        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17373    }
17374
17375    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17376            boolean oomAdj) {
17377        if (isForeground != proc.foregroundServices) {
17378            proc.foregroundServices = isForeground;
17379            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17380                    proc.info.uid);
17381            if (isForeground) {
17382                if (curProcs == null) {
17383                    curProcs = new ArrayList<ProcessRecord>();
17384                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17385                }
17386                if (!curProcs.contains(proc)) {
17387                    curProcs.add(proc);
17388                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17389                            proc.info.packageName, proc.info.uid);
17390                }
17391            } else {
17392                if (curProcs != null) {
17393                    if (curProcs.remove(proc)) {
17394                        mBatteryStatsService.noteEvent(
17395                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17396                                proc.info.packageName, proc.info.uid);
17397                        if (curProcs.size() <= 0) {
17398                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17399                        }
17400                    }
17401                }
17402            }
17403            if (oomAdj) {
17404                updateOomAdjLocked();
17405            }
17406        }
17407    }
17408
17409    private final ActivityRecord resumedAppLocked() {
17410        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17411        String pkg;
17412        int uid;
17413        if (act != null) {
17414            pkg = act.packageName;
17415            uid = act.info.applicationInfo.uid;
17416        } else {
17417            pkg = null;
17418            uid = -1;
17419        }
17420        // Has the UID or resumed package name changed?
17421        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17422                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17423            if (mCurResumedPackage != null) {
17424                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17425                        mCurResumedPackage, mCurResumedUid);
17426            }
17427            mCurResumedPackage = pkg;
17428            mCurResumedUid = uid;
17429            if (mCurResumedPackage != null) {
17430                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17431                        mCurResumedPackage, mCurResumedUid);
17432            }
17433        }
17434        return act;
17435    }
17436
17437    final boolean updateOomAdjLocked(ProcessRecord app) {
17438        final ActivityRecord TOP_ACT = resumedAppLocked();
17439        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17440        final boolean wasCached = app.cached;
17441
17442        mAdjSeq++;
17443
17444        // This is the desired cached adjusment we want to tell it to use.
17445        // If our app is currently cached, we know it, and that is it.  Otherwise,
17446        // we don't know it yet, and it needs to now be cached we will then
17447        // need to do a complete oom adj.
17448        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17449                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17450        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17451                SystemClock.uptimeMillis());
17452        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17453            // Changed to/from cached state, so apps after it in the LRU
17454            // list may also be changed.
17455            updateOomAdjLocked();
17456        }
17457        return success;
17458    }
17459
17460    final void updateOomAdjLocked() {
17461        final ActivityRecord TOP_ACT = resumedAppLocked();
17462        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17463        final long now = SystemClock.uptimeMillis();
17464        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17465        final int N = mLruProcesses.size();
17466
17467        if (false) {
17468            RuntimeException e = new RuntimeException();
17469            e.fillInStackTrace();
17470            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17471        }
17472
17473        mAdjSeq++;
17474        mNewNumServiceProcs = 0;
17475        mNewNumAServiceProcs = 0;
17476
17477        final int emptyProcessLimit;
17478        final int cachedProcessLimit;
17479        if (mProcessLimit <= 0) {
17480            emptyProcessLimit = cachedProcessLimit = 0;
17481        } else if (mProcessLimit == 1) {
17482            emptyProcessLimit = 1;
17483            cachedProcessLimit = 0;
17484        } else {
17485            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17486            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17487        }
17488
17489        // Let's determine how many processes we have running vs.
17490        // how many slots we have for background processes; we may want
17491        // to put multiple processes in a slot of there are enough of
17492        // them.
17493        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17494                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17495        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17496        if (numEmptyProcs > cachedProcessLimit) {
17497            // If there are more empty processes than our limit on cached
17498            // processes, then use the cached process limit for the factor.
17499            // This ensures that the really old empty processes get pushed
17500            // down to the bottom, so if we are running low on memory we will
17501            // have a better chance at keeping around more cached processes
17502            // instead of a gazillion empty processes.
17503            numEmptyProcs = cachedProcessLimit;
17504        }
17505        int emptyFactor = numEmptyProcs/numSlots;
17506        if (emptyFactor < 1) emptyFactor = 1;
17507        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17508        if (cachedFactor < 1) cachedFactor = 1;
17509        int stepCached = 0;
17510        int stepEmpty = 0;
17511        int numCached = 0;
17512        int numEmpty = 0;
17513        int numTrimming = 0;
17514
17515        mNumNonCachedProcs = 0;
17516        mNumCachedHiddenProcs = 0;
17517
17518        // First update the OOM adjustment for each of the
17519        // application processes based on their current state.
17520        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17521        int nextCachedAdj = curCachedAdj+1;
17522        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17523        int nextEmptyAdj = curEmptyAdj+2;
17524        for (int i=N-1; i>=0; i--) {
17525            ProcessRecord app = mLruProcesses.get(i);
17526            if (!app.killedByAm && app.thread != null) {
17527                app.procStateChanged = false;
17528                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17529
17530                // If we haven't yet assigned the final cached adj
17531                // to the process, do that now.
17532                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17533                    switch (app.curProcState) {
17534                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17535                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17536                            // This process is a cached process holding activities...
17537                            // assign it the next cached value for that type, and then
17538                            // step that cached level.
17539                            app.curRawAdj = curCachedAdj;
17540                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17541                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17542                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17543                                    + ")");
17544                            if (curCachedAdj != nextCachedAdj) {
17545                                stepCached++;
17546                                if (stepCached >= cachedFactor) {
17547                                    stepCached = 0;
17548                                    curCachedAdj = nextCachedAdj;
17549                                    nextCachedAdj += 2;
17550                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17551                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17552                                    }
17553                                }
17554                            }
17555                            break;
17556                        default:
17557                            // For everything else, assign next empty cached process
17558                            // level and bump that up.  Note that this means that
17559                            // long-running services that have dropped down to the
17560                            // cached level will be treated as empty (since their process
17561                            // state is still as a service), which is what we want.
17562                            app.curRawAdj = curEmptyAdj;
17563                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17564                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17565                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17566                                    + ")");
17567                            if (curEmptyAdj != nextEmptyAdj) {
17568                                stepEmpty++;
17569                                if (stepEmpty >= emptyFactor) {
17570                                    stepEmpty = 0;
17571                                    curEmptyAdj = nextEmptyAdj;
17572                                    nextEmptyAdj += 2;
17573                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17574                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17575                                    }
17576                                }
17577                            }
17578                            break;
17579                    }
17580                }
17581
17582                applyOomAdjLocked(app, TOP_APP, true, now);
17583
17584                // Count the number of process types.
17585                switch (app.curProcState) {
17586                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17587                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17588                        mNumCachedHiddenProcs++;
17589                        numCached++;
17590                        if (numCached > cachedProcessLimit) {
17591                            app.kill("cached #" + numCached, true);
17592                        }
17593                        break;
17594                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17595                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17596                                && app.lastActivityTime < oldTime) {
17597                            app.kill("empty for "
17598                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17599                                    / 1000) + "s", true);
17600                        } else {
17601                            numEmpty++;
17602                            if (numEmpty > emptyProcessLimit) {
17603                                app.kill("empty #" + numEmpty, true);
17604                            }
17605                        }
17606                        break;
17607                    default:
17608                        mNumNonCachedProcs++;
17609                        break;
17610                }
17611
17612                if (app.isolated && app.services.size() <= 0) {
17613                    // If this is an isolated process, and there are no
17614                    // services running in it, then the process is no longer
17615                    // needed.  We agressively kill these because we can by
17616                    // definition not re-use the same process again, and it is
17617                    // good to avoid having whatever code was running in them
17618                    // left sitting around after no longer needed.
17619                    app.kill("isolated not needed", true);
17620                }
17621
17622                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17623                        && !app.killedByAm) {
17624                    numTrimming++;
17625                }
17626            }
17627        }
17628
17629        mNumServiceProcs = mNewNumServiceProcs;
17630
17631        // Now determine the memory trimming level of background processes.
17632        // Unfortunately we need to start at the back of the list to do this
17633        // properly.  We only do this if the number of background apps we
17634        // are managing to keep around is less than half the maximum we desire;
17635        // if we are keeping a good number around, we'll let them use whatever
17636        // memory they want.
17637        final int numCachedAndEmpty = numCached + numEmpty;
17638        int memFactor;
17639        if (numCached <= ProcessList.TRIM_CACHED_APPS
17640                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17641            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17642                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17643            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17644                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17645            } else {
17646                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17647            }
17648        } else {
17649            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17650        }
17651        // We always allow the memory level to go up (better).  We only allow it to go
17652        // down if we are in a state where that is allowed, *and* the total number of processes
17653        // has gone down since last time.
17654        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17655                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17656                + " last=" + mLastNumProcesses);
17657        if (memFactor > mLastMemoryLevel) {
17658            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17659                memFactor = mLastMemoryLevel;
17660                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17661            }
17662        }
17663        mLastMemoryLevel = memFactor;
17664        mLastNumProcesses = mLruProcesses.size();
17665        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17666        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17667        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17668            if (mLowRamStartTime == 0) {
17669                mLowRamStartTime = now;
17670            }
17671            int step = 0;
17672            int fgTrimLevel;
17673            switch (memFactor) {
17674                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17675                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17676                    break;
17677                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17678                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17679                    break;
17680                default:
17681                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17682                    break;
17683            }
17684            int factor = numTrimming/3;
17685            int minFactor = 2;
17686            if (mHomeProcess != null) minFactor++;
17687            if (mPreviousProcess != null) minFactor++;
17688            if (factor < minFactor) factor = minFactor;
17689            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17690            for (int i=N-1; i>=0; i--) {
17691                ProcessRecord app = mLruProcesses.get(i);
17692                if (allChanged || app.procStateChanged) {
17693                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17694                    app.procStateChanged = false;
17695                }
17696                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17697                        && !app.killedByAm) {
17698                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17699                        try {
17700                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17701                                    "Trimming memory of " + app.processName
17702                                    + " to " + curLevel);
17703                            app.thread.scheduleTrimMemory(curLevel);
17704                        } catch (RemoteException e) {
17705                        }
17706                        if (false) {
17707                            // For now we won't do this; our memory trimming seems
17708                            // to be good enough at this point that destroying
17709                            // activities causes more harm than good.
17710                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17711                                    && app != mHomeProcess && app != mPreviousProcess) {
17712                                // Need to do this on its own message because the stack may not
17713                                // be in a consistent state at this point.
17714                                // For these apps we will also finish their activities
17715                                // to help them free memory.
17716                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17717                            }
17718                        }
17719                    }
17720                    app.trimMemoryLevel = curLevel;
17721                    step++;
17722                    if (step >= factor) {
17723                        step = 0;
17724                        switch (curLevel) {
17725                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17726                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17727                                break;
17728                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17729                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17730                                break;
17731                        }
17732                    }
17733                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17734                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17735                            && app.thread != null) {
17736                        try {
17737                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17738                                    "Trimming memory of heavy-weight " + app.processName
17739                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17740                            app.thread.scheduleTrimMemory(
17741                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17742                        } catch (RemoteException e) {
17743                        }
17744                    }
17745                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17746                } else {
17747                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17748                            || app.systemNoUi) && app.pendingUiClean) {
17749                        // If this application is now in the background and it
17750                        // had done UI, then give it the special trim level to
17751                        // have it free UI resources.
17752                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17753                        if (app.trimMemoryLevel < level && app.thread != null) {
17754                            try {
17755                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17756                                        "Trimming memory of bg-ui " + app.processName
17757                                        + " to " + level);
17758                                app.thread.scheduleTrimMemory(level);
17759                            } catch (RemoteException e) {
17760                            }
17761                        }
17762                        app.pendingUiClean = false;
17763                    }
17764                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17765                        try {
17766                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17767                                    "Trimming memory of fg " + app.processName
17768                                    + " to " + fgTrimLevel);
17769                            app.thread.scheduleTrimMemory(fgTrimLevel);
17770                        } catch (RemoteException e) {
17771                        }
17772                    }
17773                    app.trimMemoryLevel = fgTrimLevel;
17774                }
17775            }
17776        } else {
17777            if (mLowRamStartTime != 0) {
17778                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17779                mLowRamStartTime = 0;
17780            }
17781            for (int i=N-1; i>=0; i--) {
17782                ProcessRecord app = mLruProcesses.get(i);
17783                if (allChanged || app.procStateChanged) {
17784                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17785                    app.procStateChanged = false;
17786                }
17787                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17788                        || app.systemNoUi) && app.pendingUiClean) {
17789                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17790                            && app.thread != null) {
17791                        try {
17792                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17793                                    "Trimming memory of ui hidden " + app.processName
17794                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17795                            app.thread.scheduleTrimMemory(
17796                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17797                        } catch (RemoteException e) {
17798                        }
17799                    }
17800                    app.pendingUiClean = false;
17801                }
17802                app.trimMemoryLevel = 0;
17803            }
17804        }
17805
17806        if (mAlwaysFinishActivities) {
17807            // Need to do this on its own message because the stack may not
17808            // be in a consistent state at this point.
17809            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17810        }
17811
17812        if (allChanged) {
17813            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17814        }
17815
17816        if (mProcessStats.shouldWriteNowLocked(now)) {
17817            mHandler.post(new Runnable() {
17818                @Override public void run() {
17819                    synchronized (ActivityManagerService.this) {
17820                        mProcessStats.writeStateAsyncLocked();
17821                    }
17822                }
17823            });
17824        }
17825
17826        if (DEBUG_OOM_ADJ) {
17827            if (false) {
17828                RuntimeException here = new RuntimeException("here");
17829                here.fillInStackTrace();
17830                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17831            } else {
17832                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17833            }
17834        }
17835    }
17836
17837    final void trimApplications() {
17838        synchronized (this) {
17839            int i;
17840
17841            // First remove any unused application processes whose package
17842            // has been removed.
17843            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17844                final ProcessRecord app = mRemovedProcesses.get(i);
17845                if (app.activities.size() == 0
17846                        && app.curReceiver == null && app.services.size() == 0) {
17847                    Slog.i(
17848                        TAG, "Exiting empty application process "
17849                        + app.processName + " ("
17850                        + (app.thread != null ? app.thread.asBinder() : null)
17851                        + ")\n");
17852                    if (app.pid > 0 && app.pid != MY_PID) {
17853                        app.kill("empty", false);
17854                    } else {
17855                        try {
17856                            app.thread.scheduleExit();
17857                        } catch (Exception e) {
17858                            // Ignore exceptions.
17859                        }
17860                    }
17861                    cleanUpApplicationRecordLocked(app, false, true, -1);
17862                    mRemovedProcesses.remove(i);
17863
17864                    if (app.persistent) {
17865                        addAppLocked(app.info, false, null /* ABI override */);
17866                    }
17867                }
17868            }
17869
17870            // Now update the oom adj for all processes.
17871            updateOomAdjLocked();
17872        }
17873    }
17874
17875    /** This method sends the specified signal to each of the persistent apps */
17876    public void signalPersistentProcesses(int sig) throws RemoteException {
17877        if (sig != Process.SIGNAL_USR1) {
17878            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17879        }
17880
17881        synchronized (this) {
17882            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17883                    != PackageManager.PERMISSION_GRANTED) {
17884                throw new SecurityException("Requires permission "
17885                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17886            }
17887
17888            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17889                ProcessRecord r = mLruProcesses.get(i);
17890                if (r.thread != null && r.persistent) {
17891                    Process.sendSignal(r.pid, sig);
17892                }
17893            }
17894        }
17895    }
17896
17897    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17898        if (proc == null || proc == mProfileProc) {
17899            proc = mProfileProc;
17900            profileType = mProfileType;
17901            clearProfilerLocked();
17902        }
17903        if (proc == null) {
17904            return;
17905        }
17906        try {
17907            proc.thread.profilerControl(false, null, profileType);
17908        } catch (RemoteException e) {
17909            throw new IllegalStateException("Process disappeared");
17910        }
17911    }
17912
17913    private void clearProfilerLocked() {
17914        if (mProfileFd != null) {
17915            try {
17916                mProfileFd.close();
17917            } catch (IOException e) {
17918            }
17919        }
17920        mProfileApp = null;
17921        mProfileProc = null;
17922        mProfileFile = null;
17923        mProfileType = 0;
17924        mAutoStopProfiler = false;
17925        mSamplingInterval = 0;
17926    }
17927
17928    public boolean profileControl(String process, int userId, boolean start,
17929            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17930
17931        try {
17932            synchronized (this) {
17933                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17934                // its own permission.
17935                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17936                        != PackageManager.PERMISSION_GRANTED) {
17937                    throw new SecurityException("Requires permission "
17938                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17939                }
17940
17941                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17942                    throw new IllegalArgumentException("null profile info or fd");
17943                }
17944
17945                ProcessRecord proc = null;
17946                if (process != null) {
17947                    proc = findProcessLocked(process, userId, "profileControl");
17948                }
17949
17950                if (start && (proc == null || proc.thread == null)) {
17951                    throw new IllegalArgumentException("Unknown process: " + process);
17952                }
17953
17954                if (start) {
17955                    stopProfilerLocked(null, 0);
17956                    setProfileApp(proc.info, proc.processName, profilerInfo);
17957                    mProfileProc = proc;
17958                    mProfileType = profileType;
17959                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17960                    try {
17961                        fd = fd.dup();
17962                    } catch (IOException e) {
17963                        fd = null;
17964                    }
17965                    profilerInfo.profileFd = fd;
17966                    proc.thread.profilerControl(start, profilerInfo, profileType);
17967                    fd = null;
17968                    mProfileFd = null;
17969                } else {
17970                    stopProfilerLocked(proc, profileType);
17971                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17972                        try {
17973                            profilerInfo.profileFd.close();
17974                        } catch (IOException e) {
17975                        }
17976                    }
17977                }
17978
17979                return true;
17980            }
17981        } catch (RemoteException e) {
17982            throw new IllegalStateException("Process disappeared");
17983        } finally {
17984            if (profilerInfo != null && profilerInfo.profileFd != null) {
17985                try {
17986                    profilerInfo.profileFd.close();
17987                } catch (IOException e) {
17988                }
17989            }
17990        }
17991    }
17992
17993    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17994        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17995                userId, true, ALLOW_FULL_ONLY, callName, null);
17996        ProcessRecord proc = null;
17997        try {
17998            int pid = Integer.parseInt(process);
17999            synchronized (mPidsSelfLocked) {
18000                proc = mPidsSelfLocked.get(pid);
18001            }
18002        } catch (NumberFormatException e) {
18003        }
18004
18005        if (proc == null) {
18006            ArrayMap<String, SparseArray<ProcessRecord>> all
18007                    = mProcessNames.getMap();
18008            SparseArray<ProcessRecord> procs = all.get(process);
18009            if (procs != null && procs.size() > 0) {
18010                proc = procs.valueAt(0);
18011                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18012                    for (int i=1; i<procs.size(); i++) {
18013                        ProcessRecord thisProc = procs.valueAt(i);
18014                        if (thisProc.userId == userId) {
18015                            proc = thisProc;
18016                            break;
18017                        }
18018                    }
18019                }
18020            }
18021        }
18022
18023        return proc;
18024    }
18025
18026    public boolean dumpHeap(String process, int userId, boolean managed,
18027            String path, ParcelFileDescriptor fd) throws RemoteException {
18028
18029        try {
18030            synchronized (this) {
18031                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18032                // its own permission (same as profileControl).
18033                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18034                        != PackageManager.PERMISSION_GRANTED) {
18035                    throw new SecurityException("Requires permission "
18036                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18037                }
18038
18039                if (fd == null) {
18040                    throw new IllegalArgumentException("null fd");
18041                }
18042
18043                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18044                if (proc == null || proc.thread == null) {
18045                    throw new IllegalArgumentException("Unknown process: " + process);
18046                }
18047
18048                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18049                if (!isDebuggable) {
18050                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18051                        throw new SecurityException("Process not debuggable: " + proc);
18052                    }
18053                }
18054
18055                proc.thread.dumpHeap(managed, path, fd);
18056                fd = null;
18057                return true;
18058            }
18059        } catch (RemoteException e) {
18060            throw new IllegalStateException("Process disappeared");
18061        } finally {
18062            if (fd != null) {
18063                try {
18064                    fd.close();
18065                } catch (IOException e) {
18066                }
18067            }
18068        }
18069    }
18070
18071    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18072    public void monitor() {
18073        synchronized (this) { }
18074    }
18075
18076    void onCoreSettingsChange(Bundle settings) {
18077        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18078            ProcessRecord processRecord = mLruProcesses.get(i);
18079            try {
18080                if (processRecord.thread != null) {
18081                    processRecord.thread.setCoreSettings(settings);
18082                }
18083            } catch (RemoteException re) {
18084                /* ignore */
18085            }
18086        }
18087    }
18088
18089    // Multi-user methods
18090
18091    /**
18092     * Start user, if its not already running, but don't bring it to foreground.
18093     */
18094    @Override
18095    public boolean startUserInBackground(final int userId) {
18096        return startUser(userId, /* foreground */ false);
18097    }
18098
18099    /**
18100     * Start user, if its not already running, and bring it to foreground.
18101     */
18102    boolean startUserInForeground(final int userId, Dialog dlg) {
18103        boolean result = startUser(userId, /* foreground */ true);
18104        dlg.dismiss();
18105        return result;
18106    }
18107
18108    /**
18109     * Refreshes the list of users related to the current user when either a
18110     * user switch happens or when a new related user is started in the
18111     * background.
18112     */
18113    private void updateCurrentProfileIdsLocked() {
18114        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18115                mCurrentUserId, false /* enabledOnly */);
18116        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18117        for (int i = 0; i < currentProfileIds.length; i++) {
18118            currentProfileIds[i] = profiles.get(i).id;
18119        }
18120        mCurrentProfileIds = currentProfileIds;
18121
18122        synchronized (mUserProfileGroupIdsSelfLocked) {
18123            mUserProfileGroupIdsSelfLocked.clear();
18124            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18125            for (int i = 0; i < users.size(); i++) {
18126                UserInfo user = users.get(i);
18127                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18128                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18129                }
18130            }
18131        }
18132    }
18133
18134    private Set getProfileIdsLocked(int userId) {
18135        Set userIds = new HashSet<Integer>();
18136        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18137                userId, false /* enabledOnly */);
18138        for (UserInfo user : profiles) {
18139            userIds.add(Integer.valueOf(user.id));
18140        }
18141        return userIds;
18142    }
18143
18144    @Override
18145    public boolean switchUser(final int userId) {
18146        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18147        String userName;
18148        synchronized (this) {
18149            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18150            if (userInfo == null) {
18151                Slog.w(TAG, "No user info for user #" + userId);
18152                return false;
18153            }
18154            if (userInfo.isManagedProfile()) {
18155                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18156                return false;
18157            }
18158            userName = userInfo.name;
18159            mTargetUserId = userId;
18160        }
18161        mHandler.removeMessages(START_USER_SWITCH_MSG);
18162        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18163        return true;
18164    }
18165
18166    private void showUserSwitchDialog(int userId, String userName) {
18167        // The dialog will show and then initiate the user switch by calling startUserInForeground
18168        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18169                true /* above system */);
18170        d.show();
18171    }
18172
18173    private boolean startUser(final int userId, final boolean foreground) {
18174        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18175                != PackageManager.PERMISSION_GRANTED) {
18176            String msg = "Permission Denial: switchUser() from pid="
18177                    + Binder.getCallingPid()
18178                    + ", uid=" + Binder.getCallingUid()
18179                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18180            Slog.w(TAG, msg);
18181            throw new SecurityException(msg);
18182        }
18183
18184        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18185
18186        final long ident = Binder.clearCallingIdentity();
18187        try {
18188            synchronized (this) {
18189                final int oldUserId = mCurrentUserId;
18190                if (oldUserId == userId) {
18191                    return true;
18192                }
18193
18194                mStackSupervisor.setLockTaskModeLocked(null, false);
18195
18196                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18197                if (userInfo == null) {
18198                    Slog.w(TAG, "No user info for user #" + userId);
18199                    return false;
18200                }
18201                if (foreground && userInfo.isManagedProfile()) {
18202                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18203                    return false;
18204                }
18205
18206                if (foreground) {
18207                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18208                            R.anim.screen_user_enter);
18209                }
18210
18211                boolean needStart = false;
18212
18213                // If the user we are switching to is not currently started, then
18214                // we need to start it now.
18215                if (mStartedUsers.get(userId) == null) {
18216                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18217                    updateStartedUserArrayLocked();
18218                    needStart = true;
18219                }
18220
18221                final Integer userIdInt = Integer.valueOf(userId);
18222                mUserLru.remove(userIdInt);
18223                mUserLru.add(userIdInt);
18224
18225                if (foreground) {
18226                    mCurrentUserId = userId;
18227                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18228                    updateCurrentProfileIdsLocked();
18229                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18230                    // Once the internal notion of the active user has switched, we lock the device
18231                    // with the option to show the user switcher on the keyguard.
18232                    mWindowManager.lockNow(null);
18233                } else {
18234                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18235                    updateCurrentProfileIdsLocked();
18236                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18237                    mUserLru.remove(currentUserIdInt);
18238                    mUserLru.add(currentUserIdInt);
18239                }
18240
18241                final UserStartedState uss = mStartedUsers.get(userId);
18242
18243                // Make sure user is in the started state.  If it is currently
18244                // stopping, we need to knock that off.
18245                if (uss.mState == UserStartedState.STATE_STOPPING) {
18246                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18247                    // so we can just fairly silently bring the user back from
18248                    // the almost-dead.
18249                    uss.mState = UserStartedState.STATE_RUNNING;
18250                    updateStartedUserArrayLocked();
18251                    needStart = true;
18252                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18253                    // This means ACTION_SHUTDOWN has been sent, so we will
18254                    // need to treat this as a new boot of the user.
18255                    uss.mState = UserStartedState.STATE_BOOTING;
18256                    updateStartedUserArrayLocked();
18257                    needStart = true;
18258                }
18259
18260                if (uss.mState == UserStartedState.STATE_BOOTING) {
18261                    // Booting up a new user, need to tell system services about it.
18262                    // Note that this is on the same handler as scheduling of broadcasts,
18263                    // which is important because it needs to go first.
18264                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18265                }
18266
18267                if (foreground) {
18268                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18269                            oldUserId));
18270                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18271                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18272                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18273                            oldUserId, userId, uss));
18274                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18275                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18276                }
18277
18278                if (needStart) {
18279                    // Send USER_STARTED broadcast
18280                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18281                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18282                            | Intent.FLAG_RECEIVER_FOREGROUND);
18283                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18284                    broadcastIntentLocked(null, null, intent,
18285                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18286                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18287                }
18288
18289                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18290                    if (userId != UserHandle.USER_OWNER) {
18291                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18292                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18293                        broadcastIntentLocked(null, null, intent, null,
18294                                new IIntentReceiver.Stub() {
18295                                    public void performReceive(Intent intent, int resultCode,
18296                                            String data, Bundle extras, boolean ordered,
18297                                            boolean sticky, int sendingUser) {
18298                                        onUserInitialized(uss, foreground, oldUserId, userId);
18299                                    }
18300                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18301                                true, false, MY_PID, Process.SYSTEM_UID,
18302                                userId);
18303                        uss.initializing = true;
18304                    } else {
18305                        getUserManagerLocked().makeInitialized(userInfo.id);
18306                    }
18307                }
18308
18309                if (foreground) {
18310                    if (!uss.initializing) {
18311                        moveUserToForeground(uss, oldUserId, userId);
18312                    }
18313                } else {
18314                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18315                }
18316
18317                if (needStart) {
18318                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18319                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18320                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18321                    broadcastIntentLocked(null, null, intent,
18322                            null, new IIntentReceiver.Stub() {
18323                                @Override
18324                                public void performReceive(Intent intent, int resultCode, String data,
18325                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18326                                        throws RemoteException {
18327                                }
18328                            }, 0, null, null,
18329                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18330                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18331                }
18332            }
18333        } finally {
18334            Binder.restoreCallingIdentity(ident);
18335        }
18336
18337        return true;
18338    }
18339
18340    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18341        long ident = Binder.clearCallingIdentity();
18342        try {
18343            Intent intent;
18344            if (oldUserId >= 0) {
18345                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18346                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18347                int count = profiles.size();
18348                for (int i = 0; i < count; i++) {
18349                    int profileUserId = profiles.get(i).id;
18350                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18351                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18352                            | Intent.FLAG_RECEIVER_FOREGROUND);
18353                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18354                    broadcastIntentLocked(null, null, intent,
18355                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18356                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18357                }
18358            }
18359            if (newUserId >= 0) {
18360                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18361                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18362                int count = profiles.size();
18363                for (int i = 0; i < count; i++) {
18364                    int profileUserId = profiles.get(i).id;
18365                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18366                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18367                            | Intent.FLAG_RECEIVER_FOREGROUND);
18368                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18369                    broadcastIntentLocked(null, null, intent,
18370                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18371                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18372                }
18373                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18374                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18375                        | Intent.FLAG_RECEIVER_FOREGROUND);
18376                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18377                broadcastIntentLocked(null, null, intent,
18378                        null, null, 0, null, null,
18379                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18380                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18381            }
18382        } finally {
18383            Binder.restoreCallingIdentity(ident);
18384        }
18385    }
18386
18387    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18388            final int newUserId) {
18389        final int N = mUserSwitchObservers.beginBroadcast();
18390        if (N > 0) {
18391            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18392                int mCount = 0;
18393                @Override
18394                public void sendResult(Bundle data) throws RemoteException {
18395                    synchronized (ActivityManagerService.this) {
18396                        if (mCurUserSwitchCallback == this) {
18397                            mCount++;
18398                            if (mCount == N) {
18399                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18400                            }
18401                        }
18402                    }
18403                }
18404            };
18405            synchronized (this) {
18406                uss.switching = true;
18407                mCurUserSwitchCallback = callback;
18408            }
18409            for (int i=0; i<N; i++) {
18410                try {
18411                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18412                            newUserId, callback);
18413                } catch (RemoteException e) {
18414                }
18415            }
18416        } else {
18417            synchronized (this) {
18418                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18419            }
18420        }
18421        mUserSwitchObservers.finishBroadcast();
18422    }
18423
18424    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18425        synchronized (this) {
18426            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18427            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18428        }
18429    }
18430
18431    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18432        mCurUserSwitchCallback = null;
18433        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18434        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18435                oldUserId, newUserId, uss));
18436    }
18437
18438    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18439        synchronized (this) {
18440            if (foreground) {
18441                moveUserToForeground(uss, oldUserId, newUserId);
18442            }
18443        }
18444
18445        completeSwitchAndInitalize(uss, newUserId, true, false);
18446    }
18447
18448    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18449        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18450        if (homeInFront) {
18451            startHomeActivityLocked(newUserId);
18452        } else {
18453            mStackSupervisor.resumeTopActivitiesLocked();
18454        }
18455        EventLogTags.writeAmSwitchUser(newUserId);
18456        getUserManagerLocked().userForeground(newUserId);
18457        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18458    }
18459
18460    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18461        completeSwitchAndInitalize(uss, newUserId, false, true);
18462    }
18463
18464    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18465            boolean clearInitializing, boolean clearSwitching) {
18466        boolean unfrozen = false;
18467        synchronized (this) {
18468            if (clearInitializing) {
18469                uss.initializing = false;
18470                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18471            }
18472            if (clearSwitching) {
18473                uss.switching = false;
18474            }
18475            if (!uss.switching && !uss.initializing) {
18476                mWindowManager.stopFreezingScreen();
18477                unfrozen = true;
18478            }
18479        }
18480        if (unfrozen) {
18481            final int N = mUserSwitchObservers.beginBroadcast();
18482            for (int i=0; i<N; i++) {
18483                try {
18484                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18485                } catch (RemoteException e) {
18486                }
18487            }
18488            mUserSwitchObservers.finishBroadcast();
18489        }
18490    }
18491
18492    void scheduleStartProfilesLocked() {
18493        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18494            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18495                    DateUtils.SECOND_IN_MILLIS);
18496        }
18497    }
18498
18499    void startProfilesLocked() {
18500        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18501        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18502                mCurrentUserId, false /* enabledOnly */);
18503        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18504        for (UserInfo user : profiles) {
18505            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18506                    && user.id != mCurrentUserId) {
18507                toStart.add(user);
18508            }
18509        }
18510        final int n = toStart.size();
18511        int i = 0;
18512        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18513            startUserInBackground(toStart.get(i).id);
18514        }
18515        if (i < n) {
18516            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18517        }
18518    }
18519
18520    void finishUserBoot(UserStartedState uss) {
18521        synchronized (this) {
18522            if (uss.mState == UserStartedState.STATE_BOOTING
18523                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18524                uss.mState = UserStartedState.STATE_RUNNING;
18525                final int userId = uss.mHandle.getIdentifier();
18526                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18527                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18528                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18529                broadcastIntentLocked(null, null, intent,
18530                        null, null, 0, null, null,
18531                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18532                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18533            }
18534        }
18535    }
18536
18537    void finishUserSwitch(UserStartedState uss) {
18538        synchronized (this) {
18539            finishUserBoot(uss);
18540
18541            startProfilesLocked();
18542
18543            int num = mUserLru.size();
18544            int i = 0;
18545            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18546                Integer oldUserId = mUserLru.get(i);
18547                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18548                if (oldUss == null) {
18549                    // Shouldn't happen, but be sane if it does.
18550                    mUserLru.remove(i);
18551                    num--;
18552                    continue;
18553                }
18554                if (oldUss.mState == UserStartedState.STATE_STOPPING
18555                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18556                    // This user is already stopping, doesn't count.
18557                    num--;
18558                    i++;
18559                    continue;
18560                }
18561                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18562                    // Owner and current can't be stopped, but count as running.
18563                    i++;
18564                    continue;
18565                }
18566                // This is a user to be stopped.
18567                stopUserLocked(oldUserId, null);
18568                num--;
18569                i++;
18570            }
18571        }
18572    }
18573
18574    @Override
18575    public int stopUser(final int userId, final IStopUserCallback callback) {
18576        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18577                != PackageManager.PERMISSION_GRANTED) {
18578            String msg = "Permission Denial: switchUser() from pid="
18579                    + Binder.getCallingPid()
18580                    + ", uid=" + Binder.getCallingUid()
18581                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18582            Slog.w(TAG, msg);
18583            throw new SecurityException(msg);
18584        }
18585        if (userId <= 0) {
18586            throw new IllegalArgumentException("Can't stop primary user " + userId);
18587        }
18588        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18589        synchronized (this) {
18590            return stopUserLocked(userId, callback);
18591        }
18592    }
18593
18594    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18595        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18596        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18597            return ActivityManager.USER_OP_IS_CURRENT;
18598        }
18599
18600        final UserStartedState uss = mStartedUsers.get(userId);
18601        if (uss == null) {
18602            // User is not started, nothing to do...  but we do need to
18603            // callback if requested.
18604            if (callback != null) {
18605                mHandler.post(new Runnable() {
18606                    @Override
18607                    public void run() {
18608                        try {
18609                            callback.userStopped(userId);
18610                        } catch (RemoteException e) {
18611                        }
18612                    }
18613                });
18614            }
18615            return ActivityManager.USER_OP_SUCCESS;
18616        }
18617
18618        if (callback != null) {
18619            uss.mStopCallbacks.add(callback);
18620        }
18621
18622        if (uss.mState != UserStartedState.STATE_STOPPING
18623                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18624            uss.mState = UserStartedState.STATE_STOPPING;
18625            updateStartedUserArrayLocked();
18626
18627            long ident = Binder.clearCallingIdentity();
18628            try {
18629                // We are going to broadcast ACTION_USER_STOPPING and then
18630                // once that is done send a final ACTION_SHUTDOWN and then
18631                // stop the user.
18632                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18633                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18634                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18635                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18636                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18637                // This is the result receiver for the final shutdown broadcast.
18638                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18639                    @Override
18640                    public void performReceive(Intent intent, int resultCode, String data,
18641                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18642                        finishUserStop(uss);
18643                    }
18644                };
18645                // This is the result receiver for the initial stopping broadcast.
18646                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18647                    @Override
18648                    public void performReceive(Intent intent, int resultCode, String data,
18649                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18650                        // On to the next.
18651                        synchronized (ActivityManagerService.this) {
18652                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18653                                // Whoops, we are being started back up.  Abort, abort!
18654                                return;
18655                            }
18656                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18657                        }
18658                        mBatteryStatsService.noteEvent(
18659                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18660                                Integer.toString(userId), userId);
18661                        mSystemServiceManager.stopUser(userId);
18662                        broadcastIntentLocked(null, null, shutdownIntent,
18663                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18664                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18665                    }
18666                };
18667                // Kick things off.
18668                broadcastIntentLocked(null, null, stoppingIntent,
18669                        null, stoppingReceiver, 0, null, null,
18670                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18671                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18672            } finally {
18673                Binder.restoreCallingIdentity(ident);
18674            }
18675        }
18676
18677        return ActivityManager.USER_OP_SUCCESS;
18678    }
18679
18680    void finishUserStop(UserStartedState uss) {
18681        final int userId = uss.mHandle.getIdentifier();
18682        boolean stopped;
18683        ArrayList<IStopUserCallback> callbacks;
18684        synchronized (this) {
18685            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18686            if (mStartedUsers.get(userId) != uss) {
18687                stopped = false;
18688            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18689                stopped = false;
18690            } else {
18691                stopped = true;
18692                // User can no longer run.
18693                mStartedUsers.remove(userId);
18694                mUserLru.remove(Integer.valueOf(userId));
18695                updateStartedUserArrayLocked();
18696
18697                // Clean up all state and processes associated with the user.
18698                // Kill all the processes for the user.
18699                forceStopUserLocked(userId, "finish user");
18700            }
18701
18702            // Explicitly remove the old information in mRecentTasks.
18703            removeRecentTasksForUserLocked(userId);
18704        }
18705
18706        for (int i=0; i<callbacks.size(); i++) {
18707            try {
18708                if (stopped) callbacks.get(i).userStopped(userId);
18709                else callbacks.get(i).userStopAborted(userId);
18710            } catch (RemoteException e) {
18711            }
18712        }
18713
18714        if (stopped) {
18715            mSystemServiceManager.cleanupUser(userId);
18716            synchronized (this) {
18717                mStackSupervisor.removeUserLocked(userId);
18718            }
18719        }
18720    }
18721
18722    @Override
18723    public UserInfo getCurrentUser() {
18724        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18725                != PackageManager.PERMISSION_GRANTED) && (
18726                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18727                != PackageManager.PERMISSION_GRANTED)) {
18728            String msg = "Permission Denial: getCurrentUser() from pid="
18729                    + Binder.getCallingPid()
18730                    + ", uid=" + Binder.getCallingUid()
18731                    + " requires " + INTERACT_ACROSS_USERS;
18732            Slog.w(TAG, msg);
18733            throw new SecurityException(msg);
18734        }
18735        synchronized (this) {
18736            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18737            return getUserManagerLocked().getUserInfo(userId);
18738        }
18739    }
18740
18741    int getCurrentUserIdLocked() {
18742        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18743    }
18744
18745    @Override
18746    public boolean isUserRunning(int userId, boolean orStopped) {
18747        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18748                != PackageManager.PERMISSION_GRANTED) {
18749            String msg = "Permission Denial: isUserRunning() from pid="
18750                    + Binder.getCallingPid()
18751                    + ", uid=" + Binder.getCallingUid()
18752                    + " requires " + INTERACT_ACROSS_USERS;
18753            Slog.w(TAG, msg);
18754            throw new SecurityException(msg);
18755        }
18756        synchronized (this) {
18757            return isUserRunningLocked(userId, orStopped);
18758        }
18759    }
18760
18761    boolean isUserRunningLocked(int userId, boolean orStopped) {
18762        UserStartedState state = mStartedUsers.get(userId);
18763        if (state == null) {
18764            return false;
18765        }
18766        if (orStopped) {
18767            return true;
18768        }
18769        return state.mState != UserStartedState.STATE_STOPPING
18770                && state.mState != UserStartedState.STATE_SHUTDOWN;
18771    }
18772
18773    @Override
18774    public int[] getRunningUserIds() {
18775        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18776                != PackageManager.PERMISSION_GRANTED) {
18777            String msg = "Permission Denial: isUserRunning() from pid="
18778                    + Binder.getCallingPid()
18779                    + ", uid=" + Binder.getCallingUid()
18780                    + " requires " + INTERACT_ACROSS_USERS;
18781            Slog.w(TAG, msg);
18782            throw new SecurityException(msg);
18783        }
18784        synchronized (this) {
18785            return mStartedUserArray;
18786        }
18787    }
18788
18789    private void updateStartedUserArrayLocked() {
18790        int num = 0;
18791        for (int i=0; i<mStartedUsers.size();  i++) {
18792            UserStartedState uss = mStartedUsers.valueAt(i);
18793            // This list does not include stopping users.
18794            if (uss.mState != UserStartedState.STATE_STOPPING
18795                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18796                num++;
18797            }
18798        }
18799        mStartedUserArray = new int[num];
18800        num = 0;
18801        for (int i=0; i<mStartedUsers.size();  i++) {
18802            UserStartedState uss = mStartedUsers.valueAt(i);
18803            if (uss.mState != UserStartedState.STATE_STOPPING
18804                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18805                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18806                num++;
18807            }
18808        }
18809    }
18810
18811    @Override
18812    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18813        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18814                != PackageManager.PERMISSION_GRANTED) {
18815            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18816                    + Binder.getCallingPid()
18817                    + ", uid=" + Binder.getCallingUid()
18818                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18819            Slog.w(TAG, msg);
18820            throw new SecurityException(msg);
18821        }
18822
18823        mUserSwitchObservers.register(observer);
18824    }
18825
18826    @Override
18827    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18828        mUserSwitchObservers.unregister(observer);
18829    }
18830
18831    private boolean userExists(int userId) {
18832        if (userId == 0) {
18833            return true;
18834        }
18835        UserManagerService ums = getUserManagerLocked();
18836        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18837    }
18838
18839    int[] getUsersLocked() {
18840        UserManagerService ums = getUserManagerLocked();
18841        return ums != null ? ums.getUserIds() : new int[] { 0 };
18842    }
18843
18844    UserManagerService getUserManagerLocked() {
18845        if (mUserManager == null) {
18846            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18847            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18848        }
18849        return mUserManager;
18850    }
18851
18852    private int applyUserId(int uid, int userId) {
18853        return UserHandle.getUid(userId, uid);
18854    }
18855
18856    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18857        if (info == null) return null;
18858        ApplicationInfo newInfo = new ApplicationInfo(info);
18859        newInfo.uid = applyUserId(info.uid, userId);
18860        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18861                + info.packageName;
18862        return newInfo;
18863    }
18864
18865    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18866        if (aInfo == null
18867                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18868            return aInfo;
18869        }
18870
18871        ActivityInfo info = new ActivityInfo(aInfo);
18872        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18873        return info;
18874    }
18875
18876    private final class LocalService extends ActivityManagerInternal {
18877        @Override
18878        public void goingToSleep() {
18879            ActivityManagerService.this.goingToSleep();
18880        }
18881
18882        @Override
18883        public void wakingUp() {
18884            ActivityManagerService.this.wakingUp();
18885        }
18886
18887        @Override
18888        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18889                String processName, String abiOverride, int uid, Runnable crashHandler) {
18890            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18891                    processName, abiOverride, uid, crashHandler);
18892        }
18893    }
18894
18895    /**
18896     * An implementation of IAppTask, that allows an app to manage its own tasks via
18897     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18898     * only the process that calls getAppTasks() can call the AppTask methods.
18899     */
18900    class AppTaskImpl extends IAppTask.Stub {
18901        private int mTaskId;
18902        private int mCallingUid;
18903
18904        public AppTaskImpl(int taskId, int callingUid) {
18905            mTaskId = taskId;
18906            mCallingUid = callingUid;
18907        }
18908
18909        private void checkCaller() {
18910            if (mCallingUid != Binder.getCallingUid()) {
18911                throw new SecurityException("Caller " + mCallingUid
18912                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18913            }
18914        }
18915
18916        @Override
18917        public void finishAndRemoveTask() {
18918            checkCaller();
18919
18920            synchronized (ActivityManagerService.this) {
18921                long origId = Binder.clearCallingIdentity();
18922                try {
18923                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18924                    if (tr == null) {
18925                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18926                    }
18927                    // Only kill the process if we are not a new document
18928                    int flags = tr.getBaseIntent().getFlags();
18929                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18930                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18931                    removeTaskByIdLocked(mTaskId,
18932                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18933                } finally {
18934                    Binder.restoreCallingIdentity(origId);
18935                }
18936            }
18937        }
18938
18939        @Override
18940        public ActivityManager.RecentTaskInfo getTaskInfo() {
18941            checkCaller();
18942
18943            synchronized (ActivityManagerService.this) {
18944                long origId = Binder.clearCallingIdentity();
18945                try {
18946                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18947                    if (tr == null) {
18948                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18949                    }
18950                    return createRecentTaskInfoFromTaskRecord(tr);
18951                } finally {
18952                    Binder.restoreCallingIdentity(origId);
18953                }
18954            }
18955        }
18956
18957        @Override
18958        public void moveToFront() {
18959            checkCaller();
18960
18961            final TaskRecord tr;
18962            synchronized (ActivityManagerService.this) {
18963                tr = recentTaskForIdLocked(mTaskId);
18964                if (tr == null) {
18965                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18966                }
18967                if (tr.getRootActivity() != null) {
18968                    moveTaskToFrontLocked(tr.taskId, 0, null);
18969                }
18970            }
18971
18972            startActivityFromRecentsInner(tr.taskId, null);
18973        }
18974
18975        @Override
18976        public int startActivity(IBinder whoThread, String callingPackage,
18977                Intent intent, String resolvedType, Bundle options) {
18978            checkCaller();
18979
18980            int callingUser = UserHandle.getCallingUserId();
18981            TaskRecord tr;
18982            IApplicationThread appThread;
18983            synchronized (ActivityManagerService.this) {
18984                tr = recentTaskForIdLocked(mTaskId);
18985                if (tr == null) {
18986                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18987                }
18988                appThread = ApplicationThreadNative.asInterface(whoThread);
18989                if (appThread == null) {
18990                    throw new IllegalArgumentException("Bad app thread " + appThread);
18991                }
18992            }
18993            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18994                    resolvedType, null, null, null, null, 0, 0, null, null,
18995                    null, options, callingUser, null, tr);
18996        }
18997
18998        @Override
18999        public void setExcludeFromRecents(boolean exclude) {
19000            checkCaller();
19001
19002            synchronized (ActivityManagerService.this) {
19003                long origId = Binder.clearCallingIdentity();
19004                try {
19005                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19006                    if (tr == null) {
19007                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19008                    }
19009                    Intent intent = tr.getBaseIntent();
19010                    if (exclude) {
19011                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19012                    } else {
19013                        intent.setFlags(intent.getFlags()
19014                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19015                    }
19016                } finally {
19017                    Binder.restoreCallingIdentity(origId);
19018                }
19019            }
19020        }
19021    }
19022}
19023