ActivityManagerService.java revision 12a1d81de7c2e76a3eda9b997a8f8842b7ed2ff5
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    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
417
418    /**
419     * For addAppTask: cached of the last activity component that was added.
420     */
421    ComponentName mLastAddedTaskComponent;
422
423    /**
424     * For addAppTask: cached of the last activity uid that was added.
425     */
426    int mLastAddedTaskUid;
427
428    /**
429     * For addAppTask: cached of the last ActivityInfo that was added.
430     */
431    ActivityInfo mLastAddedTaskActivity;
432
433    public class PendingAssistExtras extends Binder implements Runnable {
434        public final ActivityRecord activity;
435        public boolean haveResult = false;
436        public Bundle result = null;
437        public PendingAssistExtras(ActivityRecord _activity) {
438            activity = _activity;
439        }
440        @Override
441        public void run() {
442            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
443            synchronized (this) {
444                haveResult = true;
445                notifyAll();
446            }
447        }
448    }
449
450    final ArrayList<PendingAssistExtras> mPendingAssistExtras
451            = new ArrayList<PendingAssistExtras>();
452
453    /**
454     * Process management.
455     */
456    final ProcessList mProcessList = new ProcessList();
457
458    /**
459     * All of the applications we currently have running organized by name.
460     * The keys are strings of the application package name (as
461     * returned by the package manager), and the keys are ApplicationRecord
462     * objects.
463     */
464    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
465
466    /**
467     * Tracking long-term execution of processes to look for abuse and other
468     * bad app behavior.
469     */
470    final ProcessStatsService mProcessStats;
471
472    /**
473     * The currently running isolated processes.
474     */
475    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
476
477    /**
478     * Counter for assigning isolated process uids, to avoid frequently reusing the
479     * same ones.
480     */
481    int mNextIsolatedProcessUid = 0;
482
483    /**
484     * The currently running heavy-weight process, if any.
485     */
486    ProcessRecord mHeavyWeightProcess = null;
487
488    /**
489     * The last time that various processes have crashed.
490     */
491    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
492
493    /**
494     * Information about a process that is currently marked as bad.
495     */
496    static final class BadProcessInfo {
497        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
498            this.time = time;
499            this.shortMsg = shortMsg;
500            this.longMsg = longMsg;
501            this.stack = stack;
502        }
503
504        final long time;
505        final String shortMsg;
506        final String longMsg;
507        final String stack;
508    }
509
510    /**
511     * Set of applications that we consider to be bad, and will reject
512     * incoming broadcasts from (which the user has no control over).
513     * Processes are added to this set when they have crashed twice within
514     * a minimum amount of time; they are removed from it when they are
515     * later restarted (hopefully due to some user action).  The value is the
516     * time it was added to the list.
517     */
518    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
519
520    /**
521     * All of the processes we currently have running organized by pid.
522     * The keys are the pid running the application.
523     *
524     * <p>NOTE: This object is protected by its own lock, NOT the global
525     * activity manager lock!
526     */
527    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
528
529    /**
530     * All of the processes that have been forced to be foreground.  The key
531     * is the pid of the caller who requested it (we hold a death
532     * link on it).
533     */
534    abstract class ForegroundToken implements IBinder.DeathRecipient {
535        int pid;
536        IBinder token;
537    }
538    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
539
540    /**
541     * List of records for processes that someone had tried to start before the
542     * system was ready.  We don't start them at that point, but ensure they
543     * are started by the time booting is complete.
544     */
545    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
546
547    /**
548     * List of persistent applications that are in the process
549     * of being started.
550     */
551    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Processes that are being forcibly torn down.
555     */
556    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of running applications, sorted by recent usage.
560     * The first entry in the list is the least recently used.
561     */
562    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Where in mLruProcesses that the processes hosting activities start.
566     */
567    int mLruProcessActivityStart = 0;
568
569    /**
570     * Where in mLruProcesses that the processes hosting services start.
571     * This is after (lower index) than mLruProcessesActivityStart.
572     */
573    int mLruProcessServiceStart = 0;
574
575    /**
576     * List of processes that should gc as soon as things are idle.
577     */
578    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
579
580    /**
581     * Processes we want to collect PSS data from.
582     */
583    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
584
585    /**
586     * Last time we requested PSS data of all processes.
587     */
588    long mLastFullPssTime = SystemClock.uptimeMillis();
589
590    /**
591     * If set, the next time we collect PSS data we should do a full collection
592     * with data from native processes and the kernel.
593     */
594    boolean mFullPssPending = false;
595
596    /**
597     * This is the process holding what we currently consider to be
598     * the "home" activity.
599     */
600    ProcessRecord mHomeProcess;
601
602    /**
603     * This is the process holding the activity the user last visited that
604     * is in a different process from the one they are currently in.
605     */
606    ProcessRecord mPreviousProcess;
607
608    /**
609     * The time at which the previous process was last visible.
610     */
611    long mPreviousProcessVisibleTime;
612
613    /**
614     * Which uses have been started, so are allowed to run code.
615     */
616    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
617
618    /**
619     * LRU list of history of current users.  Most recently current is at the end.
620     */
621    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
622
623    /**
624     * Constant array of the users that are currently started.
625     */
626    int[] mStartedUserArray = new int[] { 0 };
627
628    /**
629     * Registered observers of the user switching mechanics.
630     */
631    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
632            = new RemoteCallbackList<IUserSwitchObserver>();
633
634    /**
635     * Currently active user switch.
636     */
637    Object mCurUserSwitchCallback;
638
639    /**
640     * Packages that the user has asked to have run in screen size
641     * compatibility mode instead of filling the screen.
642     */
643    final CompatModePackages mCompatModePackages;
644
645    /**
646     * Set of IntentSenderRecord objects that are currently active.
647     */
648    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
649            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
650
651    /**
652     * Fingerprints (hashCode()) of stack traces that we've
653     * already logged DropBox entries for.  Guarded by itself.  If
654     * something (rogue user app) forces this over
655     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
656     */
657    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
658    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
659
660    /**
661     * Strict Mode background batched logging state.
662     *
663     * The string buffer is guarded by itself, and its lock is also
664     * used to determine if another batched write is already
665     * in-flight.
666     */
667    private final StringBuilder mStrictModeBuffer = new StringBuilder();
668
669    /**
670     * Keeps track of all IIntentReceivers that have been registered for
671     * broadcasts.  Hash keys are the receiver IBinder, hash value is
672     * a ReceiverList.
673     */
674    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
675            new HashMap<IBinder, ReceiverList>();
676
677    /**
678     * Resolver for broadcast intents to registered receivers.
679     * Holds BroadcastFilter (subclass of IntentFilter).
680     */
681    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
682            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
683        @Override
684        protected boolean allowFilterResult(
685                BroadcastFilter filter, List<BroadcastFilter> dest) {
686            IBinder target = filter.receiverList.receiver.asBinder();
687            for (int i=dest.size()-1; i>=0; i--) {
688                if (dest.get(i).receiverList.receiver.asBinder() == target) {
689                    return false;
690                }
691            }
692            return true;
693        }
694
695        @Override
696        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
697            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
698                    || userId == filter.owningUserId) {
699                return super.newResult(filter, match, userId);
700            }
701            return null;
702        }
703
704        @Override
705        protected BroadcastFilter[] newArray(int size) {
706            return new BroadcastFilter[size];
707        }
708
709        @Override
710        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
711            return packageName.equals(filter.packageName);
712        }
713    };
714
715    /**
716     * State of all active sticky broadcasts per user.  Keys are the action of the
717     * sticky Intent, values are an ArrayList of all broadcasted intents with
718     * that action (which should usually be one).  The SparseArray is keyed
719     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
720     * for stickies that are sent to all users.
721     */
722    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
723            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
724
725    final ActiveServices mServices;
726
727    /**
728     * Backup/restore process management
729     */
730    String mBackupAppName = null;
731    BackupRecord mBackupTarget = null;
732
733    final ProviderMap mProviderMap;
734
735    /**
736     * List of content providers who have clients waiting for them.  The
737     * application is currently being launched and the provider will be
738     * removed from this list once it is published.
739     */
740    final ArrayList<ContentProviderRecord> mLaunchingProviders
741            = new ArrayList<ContentProviderRecord>();
742
743    /**
744     * File storing persisted {@link #mGrantedUriPermissions}.
745     */
746    private final AtomicFile mGrantFile;
747
748    /** XML constants used in {@link #mGrantFile} */
749    private static final String TAG_URI_GRANTS = "uri-grants";
750    private static final String TAG_URI_GRANT = "uri-grant";
751    private static final String ATTR_USER_HANDLE = "userHandle";
752    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
753    private static final String ATTR_TARGET_USER_ID = "targetUserId";
754    private static final String ATTR_SOURCE_PKG = "sourcePkg";
755    private static final String ATTR_TARGET_PKG = "targetPkg";
756    private static final String ATTR_URI = "uri";
757    private static final String ATTR_MODE_FLAGS = "modeFlags";
758    private static final String ATTR_CREATED_TIME = "createdTime";
759    private static final String ATTR_PREFIX = "prefix";
760
761    /**
762     * Global set of specific {@link Uri} permissions that have been granted.
763     * This optimized lookup structure maps from {@link UriPermission#targetUid}
764     * to {@link UriPermission#uri} to {@link UriPermission}.
765     */
766    @GuardedBy("this")
767    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
768            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
769
770    public static class GrantUri {
771        public final int sourceUserId;
772        public final Uri uri;
773        public boolean prefix;
774
775        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
776            this.sourceUserId = sourceUserId;
777            this.uri = uri;
778            this.prefix = prefix;
779        }
780
781        @Override
782        public int hashCode() {
783            return toString().hashCode();
784        }
785
786        @Override
787        public boolean equals(Object o) {
788            if (o instanceof GrantUri) {
789                GrantUri other = (GrantUri) o;
790                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
791                        && prefix == other.prefix;
792            }
793            return false;
794        }
795
796        @Override
797        public String toString() {
798            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
799            if (prefix) result += " [prefix]";
800            return result;
801        }
802
803        public String toSafeString() {
804            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
805            if (prefix) result += " [prefix]";
806            return result;
807        }
808
809        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
810            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
811                    ContentProvider.getUriWithoutUserId(uri), false);
812        }
813    }
814
815    CoreSettingsObserver mCoreSettingsObserver;
816
817    /**
818     * Thread-local storage used to carry caller permissions over through
819     * indirect content-provider access.
820     */
821    private class Identity {
822        public int pid;
823        public int uid;
824
825        Identity(int _pid, int _uid) {
826            pid = _pid;
827            uid = _uid;
828        }
829    }
830
831    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
832
833    /**
834     * All information we have collected about the runtime performance of
835     * any user id that can impact battery performance.
836     */
837    final BatteryStatsService mBatteryStatsService;
838
839    /**
840     * Information about component usage
841     */
842    UsageStatsManagerInternal mUsageStatsService;
843
844    /**
845     * Information about and control over application operations
846     */
847    final AppOpsService mAppOpsService;
848
849    /**
850     * Save recent tasks information across reboots.
851     */
852    final TaskPersister mTaskPersister;
853
854    /**
855     * Current configuration information.  HistoryRecord objects are given
856     * a reference to this object to indicate which configuration they are
857     * currently running in, so this object must be kept immutable.
858     */
859    Configuration mConfiguration = new Configuration();
860
861    /**
862     * Current sequencing integer of the configuration, for skipping old
863     * configurations.
864     */
865    int mConfigurationSeq = 0;
866
867    /**
868     * Hardware-reported OpenGLES version.
869     */
870    final int GL_ES_VERSION;
871
872    /**
873     * List of initialization arguments to pass to all processes when binding applications to them.
874     * For example, references to the commonly used services.
875     */
876    HashMap<String, IBinder> mAppBindArgs;
877
878    /**
879     * Temporary to avoid allocations.  Protected by main lock.
880     */
881    final StringBuilder mStringBuilder = new StringBuilder(256);
882
883    /**
884     * Used to control how we initialize the service.
885     */
886    ComponentName mTopComponent;
887    String mTopAction = Intent.ACTION_MAIN;
888    String mTopData;
889    boolean mProcessesReady = false;
890    boolean mSystemReady = false;
891    boolean mBooting = false;
892    boolean mCallFinishBooting = false;
893    boolean mBootAnimationComplete = false;
894    boolean mWaitingUpdate = false;
895    boolean mDidUpdate = false;
896    boolean mOnBattery = false;
897    boolean mLaunchWarningShown = false;
898
899    Context mContext;
900
901    int mFactoryTest;
902
903    boolean mCheckedForSetup;
904
905    /**
906     * The time at which we will allow normal application switches again,
907     * after a call to {@link #stopAppSwitches()}.
908     */
909    long mAppSwitchesAllowedTime;
910
911    /**
912     * This is set to true after the first switch after mAppSwitchesAllowedTime
913     * is set; any switches after that will clear the time.
914     */
915    boolean mDidAppSwitch;
916
917    /**
918     * Last time (in realtime) at which we checked for power usage.
919     */
920    long mLastPowerCheckRealtime;
921
922    /**
923     * Last time (in uptime) at which we checked for power usage.
924     */
925    long mLastPowerCheckUptime;
926
927    /**
928     * Set while we are wanting to sleep, to prevent any
929     * activities from being started/resumed.
930     */
931    private boolean mSleeping = false;
932
933    /**
934     * Set while we are running a voice interaction.  This overrides
935     * sleeping while it is active.
936     */
937    private boolean mRunningVoice = false;
938
939    /**
940     * State of external calls telling us if the device is asleep.
941     */
942    private boolean mWentToSleep = false;
943
944    /**
945     * State of external call telling us if the lock screen is shown.
946     */
947    private boolean mLockScreenShown = false;
948
949    /**
950     * Set if we are shutting down the system, similar to sleeping.
951     */
952    boolean mShuttingDown = false;
953
954    /**
955     * Current sequence id for oom_adj computation traversal.
956     */
957    int mAdjSeq = 0;
958
959    /**
960     * Current sequence id for process LRU updating.
961     */
962    int mLruSeq = 0;
963
964    /**
965     * Keep track of the non-cached/empty process we last found, to help
966     * determine how to distribute cached/empty processes next time.
967     */
968    int mNumNonCachedProcs = 0;
969
970    /**
971     * Keep track of the number of cached hidden procs, to balance oom adj
972     * distribution between those and empty procs.
973     */
974    int mNumCachedHiddenProcs = 0;
975
976    /**
977     * Keep track of the number of service processes we last found, to
978     * determine on the next iteration which should be B services.
979     */
980    int mNumServiceProcs = 0;
981    int mNewNumAServiceProcs = 0;
982    int mNewNumServiceProcs = 0;
983
984    /**
985     * Allow the current computed overall memory level of the system to go down?
986     * This is set to false when we are killing processes for reasons other than
987     * memory management, so that the now smaller process list will not be taken as
988     * an indication that memory is tighter.
989     */
990    boolean mAllowLowerMemLevel = false;
991
992    /**
993     * The last computed memory level, for holding when we are in a state that
994     * processes are going away for other reasons.
995     */
996    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
997
998    /**
999     * The last total number of process we have, to determine if changes actually look
1000     * like a shrinking number of process due to lower RAM.
1001     */
1002    int mLastNumProcesses;
1003
1004    /**
1005     * The uptime of the last time we performed idle maintenance.
1006     */
1007    long mLastIdleTime = SystemClock.uptimeMillis();
1008
1009    /**
1010     * Total time spent with RAM that has been added in the past since the last idle time.
1011     */
1012    long mLowRamTimeSinceLastIdle = 0;
1013
1014    /**
1015     * If RAM is currently low, when that horrible situation started.
1016     */
1017    long mLowRamStartTime = 0;
1018
1019    /**
1020     * For reporting to battery stats the current top application.
1021     */
1022    private String mCurResumedPackage = null;
1023    private int mCurResumedUid = -1;
1024
1025    /**
1026     * For reporting to battery stats the apps currently running foreground
1027     * service.  The ProcessMap is package/uid tuples; each of these contain
1028     * an array of the currently foreground processes.
1029     */
1030    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1031            = new ProcessMap<ArrayList<ProcessRecord>>();
1032
1033    /**
1034     * This is set if we had to do a delayed dexopt of an app before launching
1035     * it, to increase the ANR timeouts in that case.
1036     */
1037    boolean mDidDexOpt;
1038
1039    /**
1040     * Set if the systemServer made a call to enterSafeMode.
1041     */
1042    boolean mSafeMode;
1043
1044    String mDebugApp = null;
1045    boolean mWaitForDebugger = false;
1046    boolean mDebugTransient = false;
1047    String mOrigDebugApp = null;
1048    boolean mOrigWaitForDebugger = false;
1049    boolean mAlwaysFinishActivities = false;
1050    IActivityController mController = null;
1051    String mProfileApp = null;
1052    ProcessRecord mProfileProc = null;
1053    String mProfileFile;
1054    ParcelFileDescriptor mProfileFd;
1055    int mSamplingInterval = 0;
1056    boolean mAutoStopProfiler = false;
1057    int mProfileType = 0;
1058    String mOpenGlTraceApp = null;
1059
1060    static class ProcessChangeItem {
1061        static final int CHANGE_ACTIVITIES = 1<<0;
1062        static final int CHANGE_PROCESS_STATE = 1<<1;
1063        int changes;
1064        int uid;
1065        int pid;
1066        int processState;
1067        boolean foregroundActivities;
1068    }
1069
1070    final RemoteCallbackList<IProcessObserver> mProcessObservers
1071            = new RemoteCallbackList<IProcessObserver>();
1072    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1073
1074    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1075            = new ArrayList<ProcessChangeItem>();
1076    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1077            = new ArrayList<ProcessChangeItem>();
1078
1079    /**
1080     * Runtime CPU use collection thread.  This object's lock is used to
1081     * perform synchronization with the thread (notifying it to run).
1082     */
1083    final Thread mProcessCpuThread;
1084
1085    /**
1086     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1087     * Must acquire this object's lock when accessing it.
1088     * NOTE: this lock will be held while doing long operations (trawling
1089     * through all processes in /proc), so it should never be acquired by
1090     * any critical paths such as when holding the main activity manager lock.
1091     */
1092    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1093            MONITOR_THREAD_CPU_USAGE);
1094    final AtomicLong mLastCpuTime = new AtomicLong(0);
1095    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1096
1097    long mLastWriteTime = 0;
1098
1099    /**
1100     * Used to retain an update lock when the foreground activity is in
1101     * immersive mode.
1102     */
1103    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1104
1105    /**
1106     * Set to true after the system has finished booting.
1107     */
1108    boolean mBooted = false;
1109
1110    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1111    int mProcessLimitOverride = -1;
1112
1113    WindowManagerService mWindowManager;
1114
1115    final ActivityThread mSystemThread;
1116
1117    // Holds the current foreground user's id
1118    int mCurrentUserId = 0;
1119    // Holds the target user's id during a user switch
1120    int mTargetUserId = UserHandle.USER_NULL;
1121    // If there are multiple profiles for the current user, their ids are here
1122    // Currently only the primary user can have managed profiles
1123    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1124
1125    /**
1126     * Mapping from each known user ID to the profile group ID it is associated with.
1127     */
1128    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1129
1130    private UserManagerService mUserManager;
1131
1132    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1133        final ProcessRecord mApp;
1134        final int mPid;
1135        final IApplicationThread mAppThread;
1136
1137        AppDeathRecipient(ProcessRecord app, int pid,
1138                IApplicationThread thread) {
1139            if (localLOGV) Slog.v(
1140                TAG, "New death recipient " + this
1141                + " for thread " + thread.asBinder());
1142            mApp = app;
1143            mPid = pid;
1144            mAppThread = thread;
1145        }
1146
1147        @Override
1148        public void binderDied() {
1149            if (localLOGV) Slog.v(
1150                TAG, "Death received in " + this
1151                + " for thread " + mAppThread.asBinder());
1152            synchronized(ActivityManagerService.this) {
1153                appDiedLocked(mApp, mPid, mAppThread);
1154            }
1155        }
1156    }
1157
1158    static final int SHOW_ERROR_MSG = 1;
1159    static final int SHOW_NOT_RESPONDING_MSG = 2;
1160    static final int SHOW_FACTORY_ERROR_MSG = 3;
1161    static final int UPDATE_CONFIGURATION_MSG = 4;
1162    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1163    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1164    static final int SERVICE_TIMEOUT_MSG = 12;
1165    static final int UPDATE_TIME_ZONE = 13;
1166    static final int SHOW_UID_ERROR_MSG = 14;
1167    static final int IM_FEELING_LUCKY_MSG = 15;
1168    static final int PROC_START_TIMEOUT_MSG = 20;
1169    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1170    static final int KILL_APPLICATION_MSG = 22;
1171    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1172    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1173    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1174    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1175    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1176    static final int CLEAR_DNS_CACHE_MSG = 28;
1177    static final int UPDATE_HTTP_PROXY_MSG = 29;
1178    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1179    static final int DISPATCH_PROCESSES_CHANGED = 31;
1180    static final int DISPATCH_PROCESS_DIED = 32;
1181    static final int REPORT_MEM_USAGE_MSG = 33;
1182    static final int REPORT_USER_SWITCH_MSG = 34;
1183    static final int CONTINUE_USER_SWITCH_MSG = 35;
1184    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1185    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1186    static final int PERSIST_URI_GRANTS_MSG = 38;
1187    static final int REQUEST_ALL_PSS_MSG = 39;
1188    static final int START_PROFILES_MSG = 40;
1189    static final int UPDATE_TIME = 41;
1190    static final int SYSTEM_USER_START_MSG = 42;
1191    static final int SYSTEM_USER_CURRENT_MSG = 43;
1192    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1193    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1194    static final int START_USER_SWITCH_MSG = 46;
1195
1196    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1197    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1198    static final int FIRST_COMPAT_MODE_MSG = 300;
1199    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1200
1201    AlertDialog mUidAlert;
1202    CompatModeDialog mCompatModeDialog;
1203    long mLastMemUsageReportTime = 0;
1204
1205    private LockToAppRequestDialog mLockToAppRequest;
1206
1207    /**
1208     * Flag whether the current user is a "monkey", i.e. whether
1209     * the UI is driven by a UI automation tool.
1210     */
1211    private boolean mUserIsMonkey;
1212
1213    /** Flag whether the device has a Recents UI */
1214    boolean mHasRecents;
1215
1216    /** The dimensions of the thumbnails in the Recents UI. */
1217    int mThumbnailWidth;
1218    int mThumbnailHeight;
1219
1220    final ServiceThread mHandlerThread;
1221    final MainHandler mHandler;
1222
1223    final class MainHandler extends Handler {
1224        public MainHandler(Looper looper) {
1225            super(looper, null, true);
1226        }
1227
1228        @Override
1229        public void handleMessage(Message msg) {
1230            switch (msg.what) {
1231            case SHOW_ERROR_MSG: {
1232                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1233                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1234                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1235                synchronized (ActivityManagerService.this) {
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    AppErrorResult res = (AppErrorResult) data.get("result");
1238                    if (proc != null && proc.crashDialog != null) {
1239                        Slog.e(TAG, "App already has crash dialog: " + proc);
1240                        if (res != null) {
1241                            res.set(0);
1242                        }
1243                        return;
1244                    }
1245                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1246                            >= Process.FIRST_APPLICATION_UID
1247                            && proc.pid != MY_PID);
1248                    for (int userId : mCurrentProfileIds) {
1249                        isBackground &= (proc.userId != userId);
1250                    }
1251                    if (isBackground && !showBackground) {
1252                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1253                        if (res != null) {
1254                            res.set(0);
1255                        }
1256                        return;
1257                    }
1258                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1259                        Dialog d = new AppErrorDialog(mContext,
1260                                ActivityManagerService.this, res, proc);
1261                        d.show();
1262                        proc.crashDialog = d;
1263                    } else {
1264                        // The device is asleep, so just pretend that the user
1265                        // saw a crash dialog and hit "force quit".
1266                        if (res != null) {
1267                            res.set(0);
1268                        }
1269                    }
1270                }
1271
1272                ensureBootCompleted();
1273            } break;
1274            case SHOW_NOT_RESPONDING_MSG: {
1275                synchronized (ActivityManagerService.this) {
1276                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1277                    ProcessRecord proc = (ProcessRecord)data.get("app");
1278                    if (proc != null && proc.anrDialog != null) {
1279                        Slog.e(TAG, "App already has anr dialog: " + proc);
1280                        return;
1281                    }
1282
1283                    Intent intent = new Intent("android.intent.action.ANR");
1284                    if (!mProcessesReady) {
1285                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1286                                | Intent.FLAG_RECEIVER_FOREGROUND);
1287                    }
1288                    broadcastIntentLocked(null, null, intent,
1289                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1290                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1291
1292                    if (mShowDialogs) {
1293                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1294                                mContext, proc, (ActivityRecord)data.get("activity"),
1295                                msg.arg1 != 0);
1296                        d.show();
1297                        proc.anrDialog = d;
1298                    } else {
1299                        // Just kill the app if there is no dialog to be shown.
1300                        killAppAtUsersRequest(proc, null);
1301                    }
1302                }
1303
1304                ensureBootCompleted();
1305            } break;
1306            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1307                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1308                synchronized (ActivityManagerService.this) {
1309                    ProcessRecord proc = (ProcessRecord) data.get("app");
1310                    if (proc == null) {
1311                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1312                        break;
1313                    }
1314                    if (proc.crashDialog != null) {
1315                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1316                        return;
1317                    }
1318                    AppErrorResult res = (AppErrorResult) data.get("result");
1319                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1320                        Dialog d = new StrictModeViolationDialog(mContext,
1321                                ActivityManagerService.this, res, proc);
1322                        d.show();
1323                        proc.crashDialog = d;
1324                    } else {
1325                        // The device is asleep, so just pretend that the user
1326                        // saw a crash dialog and hit "force quit".
1327                        res.set(0);
1328                    }
1329                }
1330                ensureBootCompleted();
1331            } break;
1332            case SHOW_FACTORY_ERROR_MSG: {
1333                Dialog d = new FactoryErrorDialog(
1334                    mContext, msg.getData().getCharSequence("msg"));
1335                d.show();
1336                ensureBootCompleted();
1337            } break;
1338            case UPDATE_CONFIGURATION_MSG: {
1339                final ContentResolver resolver = mContext.getContentResolver();
1340                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1341            } break;
1342            case GC_BACKGROUND_PROCESSES_MSG: {
1343                synchronized (ActivityManagerService.this) {
1344                    performAppGcsIfAppropriateLocked();
1345                }
1346            } break;
1347            case WAIT_FOR_DEBUGGER_MSG: {
1348                synchronized (ActivityManagerService.this) {
1349                    ProcessRecord app = (ProcessRecord)msg.obj;
1350                    if (msg.arg1 != 0) {
1351                        if (!app.waitedForDebugger) {
1352                            Dialog d = new AppWaitingForDebuggerDialog(
1353                                    ActivityManagerService.this,
1354                                    mContext, app);
1355                            app.waitDialog = d;
1356                            app.waitedForDebugger = true;
1357                            d.show();
1358                        }
1359                    } else {
1360                        if (app.waitDialog != null) {
1361                            app.waitDialog.dismiss();
1362                            app.waitDialog = null;
1363                        }
1364                    }
1365                }
1366            } break;
1367            case SERVICE_TIMEOUT_MSG: {
1368                if (mDidDexOpt) {
1369                    mDidDexOpt = false;
1370                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1371                    nmsg.obj = msg.obj;
1372                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1373                    return;
1374                }
1375                mServices.serviceTimeout((ProcessRecord)msg.obj);
1376            } break;
1377            case UPDATE_TIME_ZONE: {
1378                synchronized (ActivityManagerService.this) {
1379                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1380                        ProcessRecord r = mLruProcesses.get(i);
1381                        if (r.thread != null) {
1382                            try {
1383                                r.thread.updateTimeZone();
1384                            } catch (RemoteException ex) {
1385                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case CLEAR_DNS_CACHE_MSG: {
1392                synchronized (ActivityManagerService.this) {
1393                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1394                        ProcessRecord r = mLruProcesses.get(i);
1395                        if (r.thread != null) {
1396                            try {
1397                                r.thread.clearDnsCache();
1398                            } catch (RemoteException ex) {
1399                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1400                            }
1401                        }
1402                    }
1403                }
1404            } break;
1405            case UPDATE_HTTP_PROXY_MSG: {
1406                ProxyInfo proxy = (ProxyInfo)msg.obj;
1407                String host = "";
1408                String port = "";
1409                String exclList = "";
1410                Uri pacFileUrl = Uri.EMPTY;
1411                if (proxy != null) {
1412                    host = proxy.getHost();
1413                    port = Integer.toString(proxy.getPort());
1414                    exclList = proxy.getExclusionListAsString();
1415                    pacFileUrl = proxy.getPacFileUrl();
1416                }
1417                synchronized (ActivityManagerService.this) {
1418                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1419                        ProcessRecord r = mLruProcesses.get(i);
1420                        if (r.thread != null) {
1421                            try {
1422                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1423                            } catch (RemoteException ex) {
1424                                Slog.w(TAG, "Failed to update http proxy for: " +
1425                                        r.info.processName);
1426                            }
1427                        }
1428                    }
1429                }
1430            } break;
1431            case SHOW_UID_ERROR_MSG: {
1432                String title = "System UIDs Inconsistent";
1433                String text = "UIDs on the system are inconsistent, you need to wipe your"
1434                        + " data partition or your device will be unstable.";
1435                Log.e(TAG, title + ": " + text);
1436                if (mShowDialogs) {
1437                    // XXX This is a temporary dialog, no need to localize.
1438                    AlertDialog d = new BaseErrorDialog(mContext);
1439                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1440                    d.setCancelable(false);
1441                    d.setTitle(title);
1442                    d.setMessage(text);
1443                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1444                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1445                    mUidAlert = d;
1446                    d.show();
1447                }
1448            } break;
1449            case IM_FEELING_LUCKY_MSG: {
1450                if (mUidAlert != null) {
1451                    mUidAlert.dismiss();
1452                    mUidAlert = null;
1453                }
1454            } break;
1455            case PROC_START_TIMEOUT_MSG: {
1456                if (mDidDexOpt) {
1457                    mDidDexOpt = false;
1458                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1459                    nmsg.obj = msg.obj;
1460                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1461                    return;
1462                }
1463                ProcessRecord app = (ProcessRecord)msg.obj;
1464                synchronized (ActivityManagerService.this) {
1465                    processStartTimedOutLocked(app);
1466                }
1467            } break;
1468            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1469                synchronized (ActivityManagerService.this) {
1470                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1471                }
1472            } break;
1473            case KILL_APPLICATION_MSG: {
1474                synchronized (ActivityManagerService.this) {
1475                    int appid = msg.arg1;
1476                    boolean restart = (msg.arg2 == 1);
1477                    Bundle bundle = (Bundle)msg.obj;
1478                    String pkg = bundle.getString("pkg");
1479                    String reason = bundle.getString("reason");
1480                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1481                            false, UserHandle.USER_ALL, reason);
1482                }
1483            } break;
1484            case FINALIZE_PENDING_INTENT_MSG: {
1485                ((PendingIntentRecord)msg.obj).completeFinalize();
1486            } break;
1487            case POST_HEAVY_NOTIFICATION_MSG: {
1488                INotificationManager inm = NotificationManager.getService();
1489                if (inm == null) {
1490                    return;
1491                }
1492
1493                ActivityRecord root = (ActivityRecord)msg.obj;
1494                ProcessRecord process = root.app;
1495                if (process == null) {
1496                    return;
1497                }
1498
1499                try {
1500                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1501                    String text = mContext.getString(R.string.heavy_weight_notification,
1502                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1503                    Notification notification = new Notification();
1504                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1505                    notification.when = 0;
1506                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1507                    notification.tickerText = text;
1508                    notification.defaults = 0; // please be quiet
1509                    notification.sound = null;
1510                    notification.vibrate = null;
1511                    notification.color = mContext.getResources().getColor(
1512                            com.android.internal.R.color.system_notification_accent_color);
1513                    notification.setLatestEventInfo(context, text,
1514                            mContext.getText(R.string.heavy_weight_notification_detail),
1515                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1516                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1517                                    new UserHandle(root.userId)));
1518
1519                    try {
1520                        int[] outId = new int[1];
1521                        inm.enqueueNotificationWithTag("android", "android", null,
1522                                R.string.heavy_weight_notification,
1523                                notification, outId, root.userId);
1524                    } catch (RuntimeException e) {
1525                        Slog.w(ActivityManagerService.TAG,
1526                                "Error showing notification for heavy-weight app", e);
1527                    } catch (RemoteException e) {
1528                    }
1529                } catch (NameNotFoundException e) {
1530                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1531                }
1532            } break;
1533            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1534                INotificationManager inm = NotificationManager.getService();
1535                if (inm == null) {
1536                    return;
1537                }
1538                try {
1539                    inm.cancelNotificationWithTag("android", null,
1540                            R.string.heavy_weight_notification,  msg.arg1);
1541                } catch (RuntimeException e) {
1542                    Slog.w(ActivityManagerService.TAG,
1543                            "Error canceling notification for service", e);
1544                } catch (RemoteException e) {
1545                }
1546            } break;
1547            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1548                synchronized (ActivityManagerService.this) {
1549                    checkExcessivePowerUsageLocked(true);
1550                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1551                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1552                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1553                }
1554            } break;
1555            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1556                synchronized (ActivityManagerService.this) {
1557                    ActivityRecord ar = (ActivityRecord)msg.obj;
1558                    if (mCompatModeDialog != null) {
1559                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1560                                ar.info.applicationInfo.packageName)) {
1561                            return;
1562                        }
1563                        mCompatModeDialog.dismiss();
1564                        mCompatModeDialog = null;
1565                    }
1566                    if (ar != null && false) {
1567                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1568                                ar.packageName)) {
1569                            int mode = mCompatModePackages.computeCompatModeLocked(
1570                                    ar.info.applicationInfo);
1571                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1572                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1573                                mCompatModeDialog = new CompatModeDialog(
1574                                        ActivityManagerService.this, mContext,
1575                                        ar.info.applicationInfo);
1576                                mCompatModeDialog.show();
1577                            }
1578                        }
1579                    }
1580                }
1581                break;
1582            }
1583            case DISPATCH_PROCESSES_CHANGED: {
1584                dispatchProcessesChanged();
1585                break;
1586            }
1587            case DISPATCH_PROCESS_DIED: {
1588                final int pid = msg.arg1;
1589                final int uid = msg.arg2;
1590                dispatchProcessDied(pid, uid);
1591                break;
1592            }
1593            case REPORT_MEM_USAGE_MSG: {
1594                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1595                Thread thread = new Thread() {
1596                    @Override public void run() {
1597                        final SparseArray<ProcessMemInfo> infoMap
1598                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1599                        for (int i=0, N=memInfos.size(); i<N; i++) {
1600                            ProcessMemInfo mi = memInfos.get(i);
1601                            infoMap.put(mi.pid, mi);
1602                        }
1603                        updateCpuStatsNow();
1604                        synchronized (mProcessCpuTracker) {
1605                            final int N = mProcessCpuTracker.countStats();
1606                            for (int i=0; i<N; i++) {
1607                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1608                                if (st.vsize > 0) {
1609                                    long pss = Debug.getPss(st.pid, null);
1610                                    if (pss > 0) {
1611                                        if (infoMap.indexOfKey(st.pid) < 0) {
1612                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1613                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1614                                            mi.pss = pss;
1615                                            memInfos.add(mi);
1616                                        }
1617                                    }
1618                                }
1619                            }
1620                        }
1621
1622                        long totalPss = 0;
1623                        for (int i=0, N=memInfos.size(); i<N; i++) {
1624                            ProcessMemInfo mi = memInfos.get(i);
1625                            if (mi.pss == 0) {
1626                                mi.pss = Debug.getPss(mi.pid, null);
1627                            }
1628                            totalPss += mi.pss;
1629                        }
1630                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1631                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1632                                if (lhs.oomAdj != rhs.oomAdj) {
1633                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1634                                }
1635                                if (lhs.pss != rhs.pss) {
1636                                    return lhs.pss < rhs.pss ? 1 : -1;
1637                                }
1638                                return 0;
1639                            }
1640                        });
1641
1642                        StringBuilder tag = new StringBuilder(128);
1643                        StringBuilder stack = new StringBuilder(128);
1644                        tag.append("Low on memory -- ");
1645                        appendMemBucket(tag, totalPss, "total", false);
1646                        appendMemBucket(stack, totalPss, "total", true);
1647
1648                        StringBuilder logBuilder = new StringBuilder(1024);
1649                        logBuilder.append("Low on memory:\n");
1650
1651                        boolean firstLine = true;
1652                        int lastOomAdj = Integer.MIN_VALUE;
1653                        for (int i=0, N=memInfos.size(); i<N; i++) {
1654                            ProcessMemInfo mi = memInfos.get(i);
1655
1656                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1657                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1658                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1659                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1660                                if (lastOomAdj != mi.oomAdj) {
1661                                    lastOomAdj = mi.oomAdj;
1662                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1663                                        tag.append(" / ");
1664                                    }
1665                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1666                                        if (firstLine) {
1667                                            stack.append(":");
1668                                            firstLine = false;
1669                                        }
1670                                        stack.append("\n\t at ");
1671                                    } else {
1672                                        stack.append("$");
1673                                    }
1674                                } else {
1675                                    tag.append(" ");
1676                                    stack.append("$");
1677                                }
1678                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1679                                    appendMemBucket(tag, mi.pss, mi.name, false);
1680                                }
1681                                appendMemBucket(stack, mi.pss, mi.name, true);
1682                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1683                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1684                                    stack.append("(");
1685                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1686                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1687                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1688                                            stack.append(":");
1689                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1690                                        }
1691                                    }
1692                                    stack.append(")");
1693                                }
1694                            }
1695
1696                            logBuilder.append("  ");
1697                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1698                            logBuilder.append(' ');
1699                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1700                            logBuilder.append(' ');
1701                            ProcessList.appendRamKb(logBuilder, mi.pss);
1702                            logBuilder.append(" kB: ");
1703                            logBuilder.append(mi.name);
1704                            logBuilder.append(" (");
1705                            logBuilder.append(mi.pid);
1706                            logBuilder.append(") ");
1707                            logBuilder.append(mi.adjType);
1708                            logBuilder.append('\n');
1709                            if (mi.adjReason != null) {
1710                                logBuilder.append("                      ");
1711                                logBuilder.append(mi.adjReason);
1712                                logBuilder.append('\n');
1713                            }
1714                        }
1715
1716                        logBuilder.append("           ");
1717                        ProcessList.appendRamKb(logBuilder, totalPss);
1718                        logBuilder.append(" kB: TOTAL\n");
1719
1720                        long[] infos = new long[Debug.MEMINFO_COUNT];
1721                        Debug.getMemInfo(infos);
1722                        logBuilder.append("  MemInfo: ");
1723                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1724                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1725                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1726                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1727                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1728                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1729                            logBuilder.append("  ZRAM: ");
1730                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1731                            logBuilder.append(" kB RAM, ");
1732                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1733                            logBuilder.append(" kB swap total, ");
1734                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1735                            logBuilder.append(" kB swap free\n");
1736                        }
1737                        Slog.i(TAG, logBuilder.toString());
1738
1739                        StringBuilder dropBuilder = new StringBuilder(1024);
1740                        /*
1741                        StringWriter oomSw = new StringWriter();
1742                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1743                        StringWriter catSw = new StringWriter();
1744                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1745                        String[] emptyArgs = new String[] { };
1746                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1747                        oomPw.flush();
1748                        String oomString = oomSw.toString();
1749                        */
1750                        dropBuilder.append(stack);
1751                        dropBuilder.append('\n');
1752                        dropBuilder.append('\n');
1753                        dropBuilder.append(logBuilder);
1754                        dropBuilder.append('\n');
1755                        /*
1756                        dropBuilder.append(oomString);
1757                        dropBuilder.append('\n');
1758                        */
1759                        StringWriter catSw = new StringWriter();
1760                        synchronized (ActivityManagerService.this) {
1761                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1762                            String[] emptyArgs = new String[] { };
1763                            catPw.println();
1764                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1765                            catPw.println();
1766                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1767                                    false, false, null);
1768                            catPw.println();
1769                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1770                            catPw.flush();
1771                        }
1772                        dropBuilder.append(catSw.toString());
1773                        addErrorToDropBox("lowmem", null, "system_server", null,
1774                                null, tag.toString(), dropBuilder.toString(), null, null);
1775                        //Slog.i(TAG, "Sent to dropbox:");
1776                        //Slog.i(TAG, dropBuilder.toString());
1777                        synchronized (ActivityManagerService.this) {
1778                            long now = SystemClock.uptimeMillis();
1779                            if (mLastMemUsageReportTime < now) {
1780                                mLastMemUsageReportTime = now;
1781                            }
1782                        }
1783                    }
1784                };
1785                thread.start();
1786                break;
1787            }
1788            case START_USER_SWITCH_MSG: {
1789                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1790                break;
1791            }
1792            case REPORT_USER_SWITCH_MSG: {
1793                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1794                break;
1795            }
1796            case CONTINUE_USER_SWITCH_MSG: {
1797                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case USER_SWITCH_TIMEOUT_MSG: {
1801                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1802                break;
1803            }
1804            case IMMERSIVE_MODE_LOCK_MSG: {
1805                final boolean nextState = (msg.arg1 != 0);
1806                if (mUpdateLock.isHeld() != nextState) {
1807                    if (DEBUG_IMMERSIVE) {
1808                        final ActivityRecord r = (ActivityRecord) msg.obj;
1809                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1810                    }
1811                    if (nextState) {
1812                        mUpdateLock.acquire();
1813                    } else {
1814                        mUpdateLock.release();
1815                    }
1816                }
1817                break;
1818            }
1819            case PERSIST_URI_GRANTS_MSG: {
1820                writeGrantedUriPermissions();
1821                break;
1822            }
1823            case REQUEST_ALL_PSS_MSG: {
1824                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1825                break;
1826            }
1827            case START_PROFILES_MSG: {
1828                synchronized (ActivityManagerService.this) {
1829                    startProfilesLocked();
1830                }
1831                break;
1832            }
1833            case UPDATE_TIME: {
1834                synchronized (ActivityManagerService.this) {
1835                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1836                        ProcessRecord r = mLruProcesses.get(i);
1837                        if (r.thread != null) {
1838                            try {
1839                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1840                            } catch (RemoteException ex) {
1841                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1842                            }
1843                        }
1844                    }
1845                }
1846                break;
1847            }
1848            case SYSTEM_USER_START_MSG: {
1849                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1850                        Integer.toString(msg.arg1), msg.arg1);
1851                mSystemServiceManager.startUser(msg.arg1);
1852                break;
1853            }
1854            case SYSTEM_USER_CURRENT_MSG: {
1855                mBatteryStatsService.noteEvent(
1856                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1857                        Integer.toString(msg.arg2), msg.arg2);
1858                mBatteryStatsService.noteEvent(
1859                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1860                        Integer.toString(msg.arg1), msg.arg1);
1861                mSystemServiceManager.switchUser(msg.arg1);
1862                mLockToAppRequest.clearPrompt();
1863                break;
1864            }
1865            case ENTER_ANIMATION_COMPLETE_MSG: {
1866                synchronized (ActivityManagerService.this) {
1867                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1868                    if (r != null && r.app != null && r.app.thread != null) {
1869                        try {
1870                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1871                        } catch (RemoteException e) {
1872                        }
1873                    }
1874                }
1875                break;
1876            }
1877            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1878                enableScreenAfterBoot();
1879                break;
1880            }
1881            }
1882        }
1883    };
1884
1885    static final int COLLECT_PSS_BG_MSG = 1;
1886
1887    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1888        @Override
1889        public void handleMessage(Message msg) {
1890            switch (msg.what) {
1891            case COLLECT_PSS_BG_MSG: {
1892                long start = SystemClock.uptimeMillis();
1893                MemInfoReader memInfo = null;
1894                synchronized (ActivityManagerService.this) {
1895                    if (mFullPssPending) {
1896                        mFullPssPending = false;
1897                        memInfo = new MemInfoReader();
1898                    }
1899                }
1900                if (memInfo != null) {
1901                    updateCpuStatsNow();
1902                    long nativeTotalPss = 0;
1903                    synchronized (mProcessCpuTracker) {
1904                        final int N = mProcessCpuTracker.countStats();
1905                        for (int j=0; j<N; j++) {
1906                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1907                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1908                                // This is definitely an application process; skip it.
1909                                continue;
1910                            }
1911                            synchronized (mPidsSelfLocked) {
1912                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1913                                    // This is one of our own processes; skip it.
1914                                    continue;
1915                                }
1916                            }
1917                            nativeTotalPss += Debug.getPss(st.pid, null);
1918                        }
1919                    }
1920                    memInfo.readMemInfo();
1921                    synchronized (ActivityManagerService.this) {
1922                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1923                                + (SystemClock.uptimeMillis()-start) + "ms");
1924                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1925                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1926                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1927                                        +memInfo.getSlabSizeKb(),
1928                                nativeTotalPss);
1929                    }
1930                }
1931
1932                int i=0, num=0;
1933                long[] tmp = new long[1];
1934                do {
1935                    ProcessRecord proc;
1936                    int procState;
1937                    int pid;
1938                    synchronized (ActivityManagerService.this) {
1939                        if (i >= mPendingPssProcesses.size()) {
1940                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1941                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1942                            mPendingPssProcesses.clear();
1943                            return;
1944                        }
1945                        proc = mPendingPssProcesses.get(i);
1946                        procState = proc.pssProcState;
1947                        if (proc.thread != null && procState == proc.setProcState) {
1948                            pid = proc.pid;
1949                        } else {
1950                            proc = null;
1951                            pid = 0;
1952                        }
1953                        i++;
1954                    }
1955                    if (proc != null) {
1956                        long pss = Debug.getPss(pid, tmp);
1957                        synchronized (ActivityManagerService.this) {
1958                            if (proc.thread != null && proc.setProcState == procState
1959                                    && proc.pid == pid) {
1960                                num++;
1961                                proc.lastPssTime = SystemClock.uptimeMillis();
1962                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1963                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1964                                        + ": " + pss + " lastPss=" + proc.lastPss
1965                                        + " state=" + ProcessList.makeProcStateString(procState));
1966                                if (proc.initialIdlePss == 0) {
1967                                    proc.initialIdlePss = pss;
1968                                }
1969                                proc.lastPss = pss;
1970                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1971                                    proc.lastCachedPss = pss;
1972                                }
1973                            }
1974                        }
1975                    }
1976                } while (true);
1977            }
1978            }
1979        }
1980    };
1981
1982    /**
1983     * Monitor for package changes and update our internal state.
1984     */
1985    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1986        @Override
1987        public void onPackageRemoved(String packageName, int uid) {
1988            // Remove all tasks with activities in the specified package from the list of recent tasks
1989            synchronized (ActivityManagerService.this) {
1990                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1991                    TaskRecord tr = mRecentTasks.get(i);
1992                    ComponentName cn = tr.intent.getComponent();
1993                    if (cn != null && cn.getPackageName().equals(packageName)) {
1994                        // If the package name matches, remove the task and kill the process
1995                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1996                    }
1997                }
1998            }
1999        }
2000
2001        @Override
2002        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2003            onPackageModified(packageName);
2004            return true;
2005        }
2006
2007        @Override
2008        public void onPackageModified(String packageName) {
2009            final PackageManager pm = mContext.getPackageManager();
2010            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2011                    new ArrayList<Pair<Intent, Integer>>();
2012            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2013            // Copy the list of recent tasks so that we don't hold onto the lock on
2014            // ActivityManagerService for long periods while checking if components exist.
2015            synchronized (ActivityManagerService.this) {
2016                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2017                    TaskRecord tr = mRecentTasks.get(i);
2018                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2019                }
2020            }
2021            // Check the recent tasks and filter out all tasks with components that no longer exist.
2022            Intent tmpI = new Intent();
2023            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2024                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2025                ComponentName cn = p.first.getComponent();
2026                if (cn != null && cn.getPackageName().equals(packageName)) {
2027                    try {
2028                        // Add the task to the list to remove if the component no longer exists
2029                        tmpI.setComponent(cn);
2030                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2031                            tasksToRemove.add(p.second);
2032                        }
2033                    } catch (Exception e) {}
2034                }
2035            }
2036            // Prune all the tasks with removed components from the list of recent tasks
2037            synchronized (ActivityManagerService.this) {
2038                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2039                    // Remove the task but don't kill the process (since other components in that
2040                    // package may still be running and in the background)
2041                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2042                }
2043            }
2044        }
2045
2046        @Override
2047        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2048            // Force stop the specified packages
2049            if (packages != null) {
2050                for (String pkg : packages) {
2051                    synchronized (ActivityManagerService.this) {
2052                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2053                                "finished booting")) {
2054                            return true;
2055                        }
2056                    }
2057                }
2058            }
2059            return false;
2060        }
2061    };
2062
2063    public void setSystemProcess() {
2064        try {
2065            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2066            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2067            ServiceManager.addService("meminfo", new MemBinder(this));
2068            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2069            ServiceManager.addService("dbinfo", new DbBinder(this));
2070            if (MONITOR_CPU_USAGE) {
2071                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2072            }
2073            ServiceManager.addService("permission", new PermissionController(this));
2074
2075            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2076                    "android", STOCK_PM_FLAGS);
2077            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2078
2079            synchronized (this) {
2080                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2081                app.persistent = true;
2082                app.pid = MY_PID;
2083                app.maxAdj = ProcessList.SYSTEM_ADJ;
2084                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2085                mProcessNames.put(app.processName, app.uid, app);
2086                synchronized (mPidsSelfLocked) {
2087                    mPidsSelfLocked.put(app.pid, app);
2088                }
2089                updateLruProcessLocked(app, false, null);
2090                updateOomAdjLocked();
2091            }
2092        } catch (PackageManager.NameNotFoundException e) {
2093            throw new RuntimeException(
2094                    "Unable to find android system package", e);
2095        }
2096    }
2097
2098    public void setWindowManager(WindowManagerService wm) {
2099        mWindowManager = wm;
2100        mStackSupervisor.setWindowManager(wm);
2101    }
2102
2103    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2104        mUsageStatsService = usageStatsManager;
2105    }
2106
2107    public void startObservingNativeCrashes() {
2108        final NativeCrashListener ncl = new NativeCrashListener(this);
2109        ncl.start();
2110    }
2111
2112    public IAppOpsService getAppOpsService() {
2113        return mAppOpsService;
2114    }
2115
2116    static class MemBinder extends Binder {
2117        ActivityManagerService mActivityManagerService;
2118        MemBinder(ActivityManagerService activityManagerService) {
2119            mActivityManagerService = activityManagerService;
2120        }
2121
2122        @Override
2123        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2124            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2125                    != PackageManager.PERMISSION_GRANTED) {
2126                pw.println("Permission Denial: can't dump meminfo from from pid="
2127                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2128                        + " without permission " + android.Manifest.permission.DUMP);
2129                return;
2130            }
2131
2132            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2133        }
2134    }
2135
2136    static class GraphicsBinder extends Binder {
2137        ActivityManagerService mActivityManagerService;
2138        GraphicsBinder(ActivityManagerService activityManagerService) {
2139            mActivityManagerService = activityManagerService;
2140        }
2141
2142        @Override
2143        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2144            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2145                    != PackageManager.PERMISSION_GRANTED) {
2146                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2147                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2148                        + " without permission " + android.Manifest.permission.DUMP);
2149                return;
2150            }
2151
2152            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2153        }
2154    }
2155
2156    static class DbBinder extends Binder {
2157        ActivityManagerService mActivityManagerService;
2158        DbBinder(ActivityManagerService activityManagerService) {
2159            mActivityManagerService = activityManagerService;
2160        }
2161
2162        @Override
2163        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2164            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2165                    != PackageManager.PERMISSION_GRANTED) {
2166                pw.println("Permission Denial: can't dump dbinfo from from pid="
2167                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2168                        + " without permission " + android.Manifest.permission.DUMP);
2169                return;
2170            }
2171
2172            mActivityManagerService.dumpDbInfo(fd, pw, args);
2173        }
2174    }
2175
2176    static class CpuBinder extends Binder {
2177        ActivityManagerService mActivityManagerService;
2178        CpuBinder(ActivityManagerService activityManagerService) {
2179            mActivityManagerService = activityManagerService;
2180        }
2181
2182        @Override
2183        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2184            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2185                    != PackageManager.PERMISSION_GRANTED) {
2186                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2187                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2188                        + " without permission " + android.Manifest.permission.DUMP);
2189                return;
2190            }
2191
2192            synchronized (mActivityManagerService.mProcessCpuTracker) {
2193                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2194                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2195                        SystemClock.uptimeMillis()));
2196            }
2197        }
2198    }
2199
2200    public static final class Lifecycle extends SystemService {
2201        private final ActivityManagerService mService;
2202
2203        public Lifecycle(Context context) {
2204            super(context);
2205            mService = new ActivityManagerService(context);
2206        }
2207
2208        @Override
2209        public void onStart() {
2210            mService.start();
2211        }
2212
2213        public ActivityManagerService getService() {
2214            return mService;
2215        }
2216    }
2217
2218    // Note: This method is invoked on the main thread but may need to attach various
2219    // handlers to other threads.  So take care to be explicit about the looper.
2220    public ActivityManagerService(Context systemContext) {
2221        mContext = systemContext;
2222        mFactoryTest = FactoryTest.getMode();
2223        mSystemThread = ActivityThread.currentActivityThread();
2224
2225        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2226
2227        mHandlerThread = new ServiceThread(TAG,
2228                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2229        mHandlerThread.start();
2230        mHandler = new MainHandler(mHandlerThread.getLooper());
2231
2232        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2233                "foreground", BROADCAST_FG_TIMEOUT, false);
2234        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2235                "background", BROADCAST_BG_TIMEOUT, true);
2236        mBroadcastQueues[0] = mFgBroadcastQueue;
2237        mBroadcastQueues[1] = mBgBroadcastQueue;
2238
2239        mServices = new ActiveServices(this);
2240        mProviderMap = new ProviderMap(this);
2241
2242        // TODO: Move creation of battery stats service outside of activity manager service.
2243        File dataDir = Environment.getDataDirectory();
2244        File systemDir = new File(dataDir, "system");
2245        systemDir.mkdirs();
2246        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2247        mBatteryStatsService.getActiveStatistics().readLocked();
2248        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2249        mOnBattery = DEBUG_POWER ? true
2250                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2251        mBatteryStatsService.getActiveStatistics().setCallback(this);
2252
2253        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2254
2255        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2256
2257        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2258
2259        // User 0 is the first and only user that runs at boot.
2260        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2261        mUserLru.add(Integer.valueOf(0));
2262        updateStartedUserArrayLocked();
2263
2264        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2265            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2266
2267        mConfiguration.setToDefaults();
2268        mConfiguration.setLocale(Locale.getDefault());
2269
2270        mConfigurationSeq = mConfiguration.seq = 1;
2271        mProcessCpuTracker.init();
2272
2273        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2274        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2275        mStackSupervisor = new ActivityStackSupervisor(this);
2276        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2277
2278        mProcessCpuThread = new Thread("CpuTracker") {
2279            @Override
2280            public void run() {
2281                while (true) {
2282                    try {
2283                        try {
2284                            synchronized(this) {
2285                                final long now = SystemClock.uptimeMillis();
2286                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2287                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2288                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2289                                //        + ", write delay=" + nextWriteDelay);
2290                                if (nextWriteDelay < nextCpuDelay) {
2291                                    nextCpuDelay = nextWriteDelay;
2292                                }
2293                                if (nextCpuDelay > 0) {
2294                                    mProcessCpuMutexFree.set(true);
2295                                    this.wait(nextCpuDelay);
2296                                }
2297                            }
2298                        } catch (InterruptedException e) {
2299                        }
2300                        updateCpuStatsNow();
2301                    } catch (Exception e) {
2302                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2303                    }
2304                }
2305            }
2306        };
2307
2308        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2309
2310        Watchdog.getInstance().addMonitor(this);
2311        Watchdog.getInstance().addThread(mHandler);
2312    }
2313
2314    public void setSystemServiceManager(SystemServiceManager mgr) {
2315        mSystemServiceManager = mgr;
2316    }
2317
2318    private void start() {
2319        Process.removeAllProcessGroups();
2320        mProcessCpuThread.start();
2321
2322        mBatteryStatsService.publish(mContext);
2323        mAppOpsService.publish(mContext);
2324        Slog.d("AppOps", "AppOpsService published");
2325        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2326    }
2327
2328    public void initPowerManagement() {
2329        mStackSupervisor.initPowerManagement();
2330        mBatteryStatsService.initPowerManagement();
2331    }
2332
2333    @Override
2334    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2335            throws RemoteException {
2336        if (code == SYSPROPS_TRANSACTION) {
2337            // We need to tell all apps about the system property change.
2338            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2339            synchronized(this) {
2340                final int NP = mProcessNames.getMap().size();
2341                for (int ip=0; ip<NP; ip++) {
2342                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2343                    final int NA = apps.size();
2344                    for (int ia=0; ia<NA; ia++) {
2345                        ProcessRecord app = apps.valueAt(ia);
2346                        if (app.thread != null) {
2347                            procs.add(app.thread.asBinder());
2348                        }
2349                    }
2350                }
2351            }
2352
2353            int N = procs.size();
2354            for (int i=0; i<N; i++) {
2355                Parcel data2 = Parcel.obtain();
2356                try {
2357                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2358                } catch (RemoteException e) {
2359                }
2360                data2.recycle();
2361            }
2362        }
2363        try {
2364            return super.onTransact(code, data, reply, flags);
2365        } catch (RuntimeException e) {
2366            // The activity manager only throws security exceptions, so let's
2367            // log all others.
2368            if (!(e instanceof SecurityException)) {
2369                Slog.wtf(TAG, "Activity Manager Crash", e);
2370            }
2371            throw e;
2372        }
2373    }
2374
2375    void updateCpuStats() {
2376        final long now = SystemClock.uptimeMillis();
2377        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2378            return;
2379        }
2380        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2381            synchronized (mProcessCpuThread) {
2382                mProcessCpuThread.notify();
2383            }
2384        }
2385    }
2386
2387    void updateCpuStatsNow() {
2388        synchronized (mProcessCpuTracker) {
2389            mProcessCpuMutexFree.set(false);
2390            final long now = SystemClock.uptimeMillis();
2391            boolean haveNewCpuStats = false;
2392
2393            if (MONITOR_CPU_USAGE &&
2394                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2395                mLastCpuTime.set(now);
2396                haveNewCpuStats = true;
2397                mProcessCpuTracker.update();
2398                //Slog.i(TAG, mProcessCpu.printCurrentState());
2399                //Slog.i(TAG, "Total CPU usage: "
2400                //        + mProcessCpu.getTotalCpuPercent() + "%");
2401
2402                // Slog the cpu usage if the property is set.
2403                if ("true".equals(SystemProperties.get("events.cpu"))) {
2404                    int user = mProcessCpuTracker.getLastUserTime();
2405                    int system = mProcessCpuTracker.getLastSystemTime();
2406                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2407                    int irq = mProcessCpuTracker.getLastIrqTime();
2408                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2409                    int idle = mProcessCpuTracker.getLastIdleTime();
2410
2411                    int total = user + system + iowait + irq + softIrq + idle;
2412                    if (total == 0) total = 1;
2413
2414                    EventLog.writeEvent(EventLogTags.CPU,
2415                            ((user+system+iowait+irq+softIrq) * 100) / total,
2416                            (user * 100) / total,
2417                            (system * 100) / total,
2418                            (iowait * 100) / total,
2419                            (irq * 100) / total,
2420                            (softIrq * 100) / total);
2421                }
2422            }
2423
2424            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2425            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2426            synchronized(bstats) {
2427                synchronized(mPidsSelfLocked) {
2428                    if (haveNewCpuStats) {
2429                        if (mOnBattery) {
2430                            int perc = bstats.startAddingCpuLocked();
2431                            int totalUTime = 0;
2432                            int totalSTime = 0;
2433                            final int N = mProcessCpuTracker.countStats();
2434                            for (int i=0; i<N; i++) {
2435                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2436                                if (!st.working) {
2437                                    continue;
2438                                }
2439                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2440                                int otherUTime = (st.rel_utime*perc)/100;
2441                                int otherSTime = (st.rel_stime*perc)/100;
2442                                totalUTime += otherUTime;
2443                                totalSTime += otherSTime;
2444                                if (pr != null) {
2445                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2446                                    if (ps == null || !ps.isActive()) {
2447                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2448                                                pr.info.uid, pr.processName);
2449                                    }
2450                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2451                                            st.rel_stime-otherSTime);
2452                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2453                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2454                                } else {
2455                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2456                                    if (ps == null || !ps.isActive()) {
2457                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2458                                                bstats.mapUid(st.uid), st.name);
2459                                    }
2460                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2461                                            st.rel_stime-otherSTime);
2462                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2463                                }
2464                            }
2465                            bstats.finishAddingCpuLocked(perc, totalUTime,
2466                                    totalSTime, cpuSpeedTimes);
2467                        }
2468                    }
2469                }
2470
2471                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2472                    mLastWriteTime = now;
2473                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2474                }
2475            }
2476        }
2477    }
2478
2479    @Override
2480    public void batteryNeedsCpuUpdate() {
2481        updateCpuStatsNow();
2482    }
2483
2484    @Override
2485    public void batteryPowerChanged(boolean onBattery) {
2486        // When plugging in, update the CPU stats first before changing
2487        // the plug state.
2488        updateCpuStatsNow();
2489        synchronized (this) {
2490            synchronized(mPidsSelfLocked) {
2491                mOnBattery = DEBUG_POWER ? true : onBattery;
2492            }
2493        }
2494    }
2495
2496    /**
2497     * Initialize the application bind args. These are passed to each
2498     * process when the bindApplication() IPC is sent to the process. They're
2499     * lazily setup to make sure the services are running when they're asked for.
2500     */
2501    private HashMap<String, IBinder> getCommonServicesLocked() {
2502        if (mAppBindArgs == null) {
2503            mAppBindArgs = new HashMap<String, IBinder>();
2504
2505            // Setup the application init args
2506            mAppBindArgs.put("package", ServiceManager.getService("package"));
2507            mAppBindArgs.put("window", ServiceManager.getService("window"));
2508            mAppBindArgs.put(Context.ALARM_SERVICE,
2509                    ServiceManager.getService(Context.ALARM_SERVICE));
2510        }
2511        return mAppBindArgs;
2512    }
2513
2514    final void setFocusedActivityLocked(ActivityRecord r) {
2515        if (mFocusedActivity != r) {
2516            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2517            mFocusedActivity = r;
2518            if (r.task != null && r.task.voiceInteractor != null) {
2519                startRunningVoiceLocked();
2520            } else {
2521                finishRunningVoiceLocked();
2522            }
2523            mStackSupervisor.setFocusedStack(r);
2524            if (r != null) {
2525                mWindowManager.setFocusedApp(r.appToken, true);
2526            }
2527            applyUpdateLockStateLocked(r);
2528        }
2529    }
2530
2531    final void clearFocusedActivity(ActivityRecord r) {
2532        if (mFocusedActivity == r) {
2533            mFocusedActivity = null;
2534        }
2535    }
2536
2537    @Override
2538    public void setFocusedStack(int stackId) {
2539        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2540        synchronized (ActivityManagerService.this) {
2541            ActivityStack stack = mStackSupervisor.getStack(stackId);
2542            if (stack != null) {
2543                ActivityRecord r = stack.topRunningActivityLocked(null);
2544                if (r != null) {
2545                    setFocusedActivityLocked(r);
2546                }
2547            }
2548        }
2549    }
2550
2551    @Override
2552    public void notifyActivityDrawn(IBinder token) {
2553        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2554        synchronized (this) {
2555            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2556            if (r != null) {
2557                r.task.stack.notifyActivityDrawnLocked(r);
2558            }
2559        }
2560    }
2561
2562    final void applyUpdateLockStateLocked(ActivityRecord r) {
2563        // Modifications to the UpdateLock state are done on our handler, outside
2564        // the activity manager's locks.  The new state is determined based on the
2565        // state *now* of the relevant activity record.  The object is passed to
2566        // the handler solely for logging detail, not to be consulted/modified.
2567        final boolean nextState = r != null && r.immersive;
2568        mHandler.sendMessage(
2569                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2570    }
2571
2572    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2573        Message msg = Message.obtain();
2574        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2575        msg.obj = r.task.askedCompatMode ? null : r;
2576        mHandler.sendMessage(msg);
2577    }
2578
2579    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2580            String what, Object obj, ProcessRecord srcApp) {
2581        app.lastActivityTime = now;
2582
2583        if (app.activities.size() > 0) {
2584            // Don't want to touch dependent processes that are hosting activities.
2585            return index;
2586        }
2587
2588        int lrui = mLruProcesses.lastIndexOf(app);
2589        if (lrui < 0) {
2590            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2591                    + what + " " + obj + " from " + srcApp);
2592            return index;
2593        }
2594
2595        if (lrui >= index) {
2596            // Don't want to cause this to move dependent processes *back* in the
2597            // list as if they were less frequently used.
2598            return index;
2599        }
2600
2601        if (lrui >= mLruProcessActivityStart) {
2602            // Don't want to touch dependent processes that are hosting activities.
2603            return index;
2604        }
2605
2606        mLruProcesses.remove(lrui);
2607        if (index > 0) {
2608            index--;
2609        }
2610        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2611                + " in LRU list: " + app);
2612        mLruProcesses.add(index, app);
2613        return index;
2614    }
2615
2616    final void removeLruProcessLocked(ProcessRecord app) {
2617        int lrui = mLruProcesses.lastIndexOf(app);
2618        if (lrui >= 0) {
2619            if (lrui <= mLruProcessActivityStart) {
2620                mLruProcessActivityStart--;
2621            }
2622            if (lrui <= mLruProcessServiceStart) {
2623                mLruProcessServiceStart--;
2624            }
2625            mLruProcesses.remove(lrui);
2626        }
2627    }
2628
2629    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2630            ProcessRecord client) {
2631        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2632                || app.treatLikeActivity;
2633        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2634        if (!activityChange && hasActivity) {
2635            // The process has activities, so we are only allowing activity-based adjustments
2636            // to move it.  It should be kept in the front of the list with other
2637            // processes that have activities, and we don't want those to change their
2638            // order except due to activity operations.
2639            return;
2640        }
2641
2642        mLruSeq++;
2643        final long now = SystemClock.uptimeMillis();
2644        app.lastActivityTime = now;
2645
2646        // First a quick reject: if the app is already at the position we will
2647        // put it, then there is nothing to do.
2648        if (hasActivity) {
2649            final int N = mLruProcesses.size();
2650            if (N > 0 && mLruProcesses.get(N-1) == app) {
2651                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2652                return;
2653            }
2654        } else {
2655            if (mLruProcessServiceStart > 0
2656                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2657                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2658                return;
2659            }
2660        }
2661
2662        int lrui = mLruProcesses.lastIndexOf(app);
2663
2664        if (app.persistent && lrui >= 0) {
2665            // We don't care about the position of persistent processes, as long as
2666            // they are in the list.
2667            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2668            return;
2669        }
2670
2671        /* In progress: compute new position first, so we can avoid doing work
2672           if the process is not actually going to move.  Not yet working.
2673        int addIndex;
2674        int nextIndex;
2675        boolean inActivity = false, inService = false;
2676        if (hasActivity) {
2677            // Process has activities, put it at the very tipsy-top.
2678            addIndex = mLruProcesses.size();
2679            nextIndex = mLruProcessServiceStart;
2680            inActivity = true;
2681        } else if (hasService) {
2682            // Process has services, put it at the top of the service list.
2683            addIndex = mLruProcessActivityStart;
2684            nextIndex = mLruProcessServiceStart;
2685            inActivity = true;
2686            inService = true;
2687        } else  {
2688            // Process not otherwise of interest, it goes to the top of the non-service area.
2689            addIndex = mLruProcessServiceStart;
2690            if (client != null) {
2691                int clientIndex = mLruProcesses.lastIndexOf(client);
2692                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2693                        + app);
2694                if (clientIndex >= 0 && addIndex > clientIndex) {
2695                    addIndex = clientIndex;
2696                }
2697            }
2698            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2699        }
2700
2701        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2702                + mLruProcessActivityStart + "): " + app);
2703        */
2704
2705        if (lrui >= 0) {
2706            if (lrui < mLruProcessActivityStart) {
2707                mLruProcessActivityStart--;
2708            }
2709            if (lrui < mLruProcessServiceStart) {
2710                mLruProcessServiceStart--;
2711            }
2712            /*
2713            if (addIndex > lrui) {
2714                addIndex--;
2715            }
2716            if (nextIndex > lrui) {
2717                nextIndex--;
2718            }
2719            */
2720            mLruProcesses.remove(lrui);
2721        }
2722
2723        /*
2724        mLruProcesses.add(addIndex, app);
2725        if (inActivity) {
2726            mLruProcessActivityStart++;
2727        }
2728        if (inService) {
2729            mLruProcessActivityStart++;
2730        }
2731        */
2732
2733        int nextIndex;
2734        if (hasActivity) {
2735            final int N = mLruProcesses.size();
2736            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2737                // Process doesn't have activities, but has clients with
2738                // activities...  move it up, but one below the top (the top
2739                // should always have a real activity).
2740                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2741                mLruProcesses.add(N-1, app);
2742                // To keep it from spamming the LRU list (by making a bunch of clients),
2743                // we will push down any other entries owned by the app.
2744                final int uid = app.info.uid;
2745                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2746                    ProcessRecord subProc = mLruProcesses.get(i);
2747                    if (subProc.info.uid == uid) {
2748                        // We want to push this one down the list.  If the process after
2749                        // it is for the same uid, however, don't do so, because we don't
2750                        // want them internally to be re-ordered.
2751                        if (mLruProcesses.get(i-1).info.uid != uid) {
2752                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2753                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2754                            ProcessRecord tmp = mLruProcesses.get(i);
2755                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2756                            mLruProcesses.set(i-1, tmp);
2757                            i--;
2758                        }
2759                    } else {
2760                        // A gap, we can stop here.
2761                        break;
2762                    }
2763                }
2764            } else {
2765                // Process has activities, put it at the very tipsy-top.
2766                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2767                mLruProcesses.add(app);
2768            }
2769            nextIndex = mLruProcessServiceStart;
2770        } else if (hasService) {
2771            // Process has services, put it at the top of the service list.
2772            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2773            mLruProcesses.add(mLruProcessActivityStart, app);
2774            nextIndex = mLruProcessServiceStart;
2775            mLruProcessActivityStart++;
2776        } else  {
2777            // Process not otherwise of interest, it goes to the top of the non-service area.
2778            int index = mLruProcessServiceStart;
2779            if (client != null) {
2780                // If there is a client, don't allow the process to be moved up higher
2781                // in the list than that client.
2782                int clientIndex = mLruProcesses.lastIndexOf(client);
2783                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2784                        + " when updating " + app);
2785                if (clientIndex <= lrui) {
2786                    // Don't allow the client index restriction to push it down farther in the
2787                    // list than it already is.
2788                    clientIndex = lrui;
2789                }
2790                if (clientIndex >= 0 && index > clientIndex) {
2791                    index = clientIndex;
2792                }
2793            }
2794            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2795            mLruProcesses.add(index, app);
2796            nextIndex = index-1;
2797            mLruProcessActivityStart++;
2798            mLruProcessServiceStart++;
2799        }
2800
2801        // If the app is currently using a content provider or service,
2802        // bump those processes as well.
2803        for (int j=app.connections.size()-1; j>=0; j--) {
2804            ConnectionRecord cr = app.connections.valueAt(j);
2805            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2806                    && cr.binding.service.app != null
2807                    && cr.binding.service.app.lruSeq != mLruSeq
2808                    && !cr.binding.service.app.persistent) {
2809                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2810                        "service connection", cr, app);
2811            }
2812        }
2813        for (int j=app.conProviders.size()-1; j>=0; j--) {
2814            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2815            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2816                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2817                        "provider reference", cpr, app);
2818            }
2819        }
2820    }
2821
2822    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2823        if (uid == Process.SYSTEM_UID) {
2824            // The system gets to run in any process.  If there are multiple
2825            // processes with the same uid, just pick the first (this
2826            // should never happen).
2827            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2828            if (procs == null) return null;
2829            final int N = procs.size();
2830            for (int i = 0; i < N; i++) {
2831                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2832            }
2833        }
2834        ProcessRecord proc = mProcessNames.get(processName, uid);
2835        if (false && proc != null && !keepIfLarge
2836                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2837                && proc.lastCachedPss >= 4000) {
2838            // Turn this condition on to cause killing to happen regularly, for testing.
2839            if (proc.baseProcessTracker != null) {
2840                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2841            }
2842            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2843        } else if (proc != null && !keepIfLarge
2844                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2845                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2846            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2847            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2848                if (proc.baseProcessTracker != null) {
2849                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2850                }
2851                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2852            }
2853        }
2854        return proc;
2855    }
2856
2857    void ensurePackageDexOpt(String packageName) {
2858        IPackageManager pm = AppGlobals.getPackageManager();
2859        try {
2860            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2861                mDidDexOpt = true;
2862            }
2863        } catch (RemoteException e) {
2864        }
2865    }
2866
2867    boolean isNextTransitionForward() {
2868        int transit = mWindowManager.getPendingAppTransition();
2869        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2870                || transit == AppTransition.TRANSIT_TASK_OPEN
2871                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2872    }
2873
2874    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2875            String processName, String abiOverride, int uid, Runnable crashHandler) {
2876        synchronized(this) {
2877            ApplicationInfo info = new ApplicationInfo();
2878            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2879            // For isolated processes, the former contains the parent's uid and the latter the
2880            // actual uid of the isolated process.
2881            // In the special case introduced by this method (which is, starting an isolated
2882            // process directly from the SystemServer without an actual parent app process) the
2883            // closest thing to a parent's uid is SYSTEM_UID.
2884            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2885            // the |isolated| logic in the ProcessRecord constructor.
2886            info.uid = Process.SYSTEM_UID;
2887            info.processName = processName;
2888            info.className = entryPoint;
2889            info.packageName = "android";
2890            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2891                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2892                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2893                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2894                    crashHandler);
2895            return proc != null ? proc.pid : 0;
2896        }
2897    }
2898
2899    final ProcessRecord startProcessLocked(String processName,
2900            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2901            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2902            boolean isolated, boolean keepIfLarge) {
2903        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2904                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2905                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2906                null /* crashHandler */);
2907    }
2908
2909    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2910            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2911            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2912            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2913        long startTime = SystemClock.elapsedRealtime();
2914        ProcessRecord app;
2915        if (!isolated) {
2916            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2917            checkTime(startTime, "startProcess: after getProcessRecord");
2918        } else {
2919            // If this is an isolated process, it can't re-use an existing process.
2920            app = null;
2921        }
2922        // We don't have to do anything more if:
2923        // (1) There is an existing application record; and
2924        // (2) The caller doesn't think it is dead, OR there is no thread
2925        //     object attached to it so we know it couldn't have crashed; and
2926        // (3) There is a pid assigned to it, so it is either starting or
2927        //     already running.
2928        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2929                + " app=" + app + " knownToBeDead=" + knownToBeDead
2930                + " thread=" + (app != null ? app.thread : null)
2931                + " pid=" + (app != null ? app.pid : -1));
2932        if (app != null && app.pid > 0) {
2933            if (!knownToBeDead || app.thread == null) {
2934                // We already have the app running, or are waiting for it to
2935                // come up (we have a pid but not yet its thread), so keep it.
2936                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2937                // If this is a new package in the process, add the package to the list
2938                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2939                checkTime(startTime, "startProcess: done, added package to proc");
2940                return app;
2941            }
2942
2943            // An application record is attached to a previous process,
2944            // clean it up now.
2945            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2946            checkTime(startTime, "startProcess: bad proc running, killing");
2947            Process.killProcessGroup(app.info.uid, app.pid);
2948            handleAppDiedLocked(app, true, true);
2949            checkTime(startTime, "startProcess: done killing old proc");
2950        }
2951
2952        String hostingNameStr = hostingName != null
2953                ? hostingName.flattenToShortString() : null;
2954
2955        if (!isolated) {
2956            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2957                // If we are in the background, then check to see if this process
2958                // is bad.  If so, we will just silently fail.
2959                if (mBadProcesses.get(info.processName, info.uid) != null) {
2960                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2961                            + "/" + info.processName);
2962                    return null;
2963                }
2964            } else {
2965                // When the user is explicitly starting a process, then clear its
2966                // crash count so that we won't make it bad until they see at
2967                // least one crash dialog again, and make the process good again
2968                // if it had been bad.
2969                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2970                        + "/" + info.processName);
2971                mProcessCrashTimes.remove(info.processName, info.uid);
2972                if (mBadProcesses.get(info.processName, info.uid) != null) {
2973                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2974                            UserHandle.getUserId(info.uid), info.uid,
2975                            info.processName);
2976                    mBadProcesses.remove(info.processName, info.uid);
2977                    if (app != null) {
2978                        app.bad = false;
2979                    }
2980                }
2981            }
2982        }
2983
2984        if (app == null) {
2985            checkTime(startTime, "startProcess: creating new process record");
2986            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2987            app.crashHandler = crashHandler;
2988            if (app == null) {
2989                Slog.w(TAG, "Failed making new process record for "
2990                        + processName + "/" + info.uid + " isolated=" + isolated);
2991                return null;
2992            }
2993            mProcessNames.put(processName, app.uid, app);
2994            if (isolated) {
2995                mIsolatedProcesses.put(app.uid, app);
2996            }
2997            checkTime(startTime, "startProcess: done creating new process record");
2998        } else {
2999            // If this is a new package in the process, add the package to the list
3000            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3001            checkTime(startTime, "startProcess: added package to existing proc");
3002        }
3003
3004        // If the system is not ready yet, then hold off on starting this
3005        // process until it is.
3006        if (!mProcessesReady
3007                && !isAllowedWhileBooting(info)
3008                && !allowWhileBooting) {
3009            if (!mProcessesOnHold.contains(app)) {
3010                mProcessesOnHold.add(app);
3011            }
3012            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3013            checkTime(startTime, "startProcess: returning with proc on hold");
3014            return app;
3015        }
3016
3017        checkTime(startTime, "startProcess: stepping in to startProcess");
3018        startProcessLocked(
3019                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3020        checkTime(startTime, "startProcess: done starting proc!");
3021        return (app.pid != 0) ? app : null;
3022    }
3023
3024    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3025        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3026    }
3027
3028    private final void startProcessLocked(ProcessRecord app,
3029            String hostingType, String hostingNameStr) {
3030        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3031                null /* entryPoint */, null /* entryPointArgs */);
3032    }
3033
3034    private final void startProcessLocked(ProcessRecord app, String hostingType,
3035            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3036        long startTime = SystemClock.elapsedRealtime();
3037        if (app.pid > 0 && app.pid != MY_PID) {
3038            checkTime(startTime, "startProcess: removing from pids map");
3039            synchronized (mPidsSelfLocked) {
3040                mPidsSelfLocked.remove(app.pid);
3041                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3042            }
3043            checkTime(startTime, "startProcess: done removing from pids map");
3044            app.setPid(0);
3045        }
3046
3047        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3048                "startProcessLocked removing on hold: " + app);
3049        mProcessesOnHold.remove(app);
3050
3051        checkTime(startTime, "startProcess: starting to update cpu stats");
3052        updateCpuStats();
3053        checkTime(startTime, "startProcess: done updating cpu stats");
3054
3055        try {
3056            int uid = app.uid;
3057
3058            int[] gids = null;
3059            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3060            if (!app.isolated) {
3061                int[] permGids = null;
3062                try {
3063                    checkTime(startTime, "startProcess: getting gids from package manager");
3064                    final PackageManager pm = mContext.getPackageManager();
3065                    permGids = pm.getPackageGids(app.info.packageName);
3066
3067                    if (Environment.isExternalStorageEmulated()) {
3068                        checkTime(startTime, "startProcess: checking external storage perm");
3069                        if (pm.checkPermission(
3070                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3071                                app.info.packageName) == PERMISSION_GRANTED) {
3072                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3073                        } else {
3074                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3075                        }
3076                    }
3077                } catch (PackageManager.NameNotFoundException e) {
3078                    Slog.w(TAG, "Unable to retrieve gids", e);
3079                }
3080
3081                /*
3082                 * Add shared application and profile GIDs so applications can share some
3083                 * resources like shared libraries and access user-wide resources
3084                 */
3085                if (permGids == null) {
3086                    gids = new int[2];
3087                } else {
3088                    gids = new int[permGids.length + 2];
3089                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3090                }
3091                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3092                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3093            }
3094            checkTime(startTime, "startProcess: building args");
3095            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3096                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3097                        && mTopComponent != null
3098                        && app.processName.equals(mTopComponent.getPackageName())) {
3099                    uid = 0;
3100                }
3101                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3102                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3103                    uid = 0;
3104                }
3105            }
3106            int debugFlags = 0;
3107            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3108                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3109                // Also turn on CheckJNI for debuggable apps. It's quite
3110                // awkward to turn on otherwise.
3111                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3112            }
3113            // Run the app in safe mode if its manifest requests so or the
3114            // system is booted in safe mode.
3115            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3116                mSafeMode == true) {
3117                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3118            }
3119            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3120                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3121            }
3122            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3123                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3124            }
3125            if ("1".equals(SystemProperties.get("debug.assert"))) {
3126                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3127            }
3128
3129            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3130            if (requiredAbi == null) {
3131                requiredAbi = Build.SUPPORTED_ABIS[0];
3132            }
3133
3134            String instructionSet = null;
3135            if (app.info.primaryCpuAbi != null) {
3136                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3137            }
3138
3139            // Start the process.  It will either succeed and return a result containing
3140            // the PID of the new process, or else throw a RuntimeException.
3141            boolean isActivityProcess = (entryPoint == null);
3142            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3143            checkTime(startTime, "startProcess: asking zygote to start proc");
3144            Process.ProcessStartResult startResult = Process.start(entryPoint,
3145                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3146                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3147                    entryPointArgs);
3148            checkTime(startTime, "startProcess: returned from zygote!");
3149
3150            if (app.isolated) {
3151                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3152            }
3153            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3154            checkTime(startTime, "startProcess: done updating battery stats");
3155
3156            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3157                    UserHandle.getUserId(uid), startResult.pid, uid,
3158                    app.processName, hostingType,
3159                    hostingNameStr != null ? hostingNameStr : "");
3160
3161            if (app.persistent) {
3162                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3163            }
3164
3165            checkTime(startTime, "startProcess: building log message");
3166            StringBuilder buf = mStringBuilder;
3167            buf.setLength(0);
3168            buf.append("Start proc ");
3169            buf.append(app.processName);
3170            if (!isActivityProcess) {
3171                buf.append(" [");
3172                buf.append(entryPoint);
3173                buf.append("]");
3174            }
3175            buf.append(" for ");
3176            buf.append(hostingType);
3177            if (hostingNameStr != null) {
3178                buf.append(" ");
3179                buf.append(hostingNameStr);
3180            }
3181            buf.append(": pid=");
3182            buf.append(startResult.pid);
3183            buf.append(" uid=");
3184            buf.append(uid);
3185            buf.append(" gids={");
3186            if (gids != null) {
3187                for (int gi=0; gi<gids.length; gi++) {
3188                    if (gi != 0) buf.append(", ");
3189                    buf.append(gids[gi]);
3190
3191                }
3192            }
3193            buf.append("}");
3194            if (requiredAbi != null) {
3195                buf.append(" abi=");
3196                buf.append(requiredAbi);
3197            }
3198            Slog.i(TAG, buf.toString());
3199            app.setPid(startResult.pid);
3200            app.usingWrapper = startResult.usingWrapper;
3201            app.removed = false;
3202            app.killedByAm = false;
3203            checkTime(startTime, "startProcess: starting to update pids map");
3204            synchronized (mPidsSelfLocked) {
3205                this.mPidsSelfLocked.put(startResult.pid, app);
3206                if (isActivityProcess) {
3207                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3208                    msg.obj = app;
3209                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3210                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3211                }
3212            }
3213            checkTime(startTime, "startProcess: done updating pids map");
3214        } catch (RuntimeException e) {
3215            // XXX do better error recovery.
3216            app.setPid(0);
3217            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3218            if (app.isolated) {
3219                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3220            }
3221            Slog.e(TAG, "Failure starting process " + app.processName, e);
3222        }
3223    }
3224
3225    void updateUsageStats(ActivityRecord component, boolean resumed) {
3226        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3227        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3228        if (resumed) {
3229            if (mUsageStatsService != null) {
3230                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3231                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3232            }
3233            synchronized (stats) {
3234                stats.noteActivityResumedLocked(component.app.uid);
3235            }
3236        } else {
3237            if (mUsageStatsService != null) {
3238                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3239                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3240            }
3241            synchronized (stats) {
3242                stats.noteActivityPausedLocked(component.app.uid);
3243            }
3244        }
3245    }
3246
3247    Intent getHomeIntent() {
3248        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3249        intent.setComponent(mTopComponent);
3250        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3251            intent.addCategory(Intent.CATEGORY_HOME);
3252        }
3253        return intent;
3254    }
3255
3256    boolean startHomeActivityLocked(int userId) {
3257        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3258                && mTopAction == null) {
3259            // We are running in factory test mode, but unable to find
3260            // the factory test app, so just sit around displaying the
3261            // error message and don't try to start anything.
3262            return false;
3263        }
3264        Intent intent = getHomeIntent();
3265        ActivityInfo aInfo =
3266            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3267        if (aInfo != null) {
3268            intent.setComponent(new ComponentName(
3269                    aInfo.applicationInfo.packageName, aInfo.name));
3270            // Don't do this if the home app is currently being
3271            // instrumented.
3272            aInfo = new ActivityInfo(aInfo);
3273            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3274            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3275                    aInfo.applicationInfo.uid, true);
3276            if (app == null || app.instrumentationClass == null) {
3277                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3278                mStackSupervisor.startHomeActivity(intent, aInfo);
3279            }
3280        }
3281
3282        return true;
3283    }
3284
3285    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3286        ActivityInfo ai = null;
3287        ComponentName comp = intent.getComponent();
3288        try {
3289            if (comp != null) {
3290                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3291            } else {
3292                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3293                        intent,
3294                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3295                            flags, userId);
3296
3297                if (info != null) {
3298                    ai = info.activityInfo;
3299                }
3300            }
3301        } catch (RemoteException e) {
3302            // ignore
3303        }
3304
3305        return ai;
3306    }
3307
3308    /**
3309     * Starts the "new version setup screen" if appropriate.
3310     */
3311    void startSetupActivityLocked() {
3312        // Only do this once per boot.
3313        if (mCheckedForSetup) {
3314            return;
3315        }
3316
3317        // We will show this screen if the current one is a different
3318        // version than the last one shown, and we are not running in
3319        // low-level factory test mode.
3320        final ContentResolver resolver = mContext.getContentResolver();
3321        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3322                Settings.Global.getInt(resolver,
3323                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3324            mCheckedForSetup = true;
3325
3326            // See if we should be showing the platform update setup UI.
3327            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3328            List<ResolveInfo> ris = mContext.getPackageManager()
3329                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3330
3331            // We don't allow third party apps to replace this.
3332            ResolveInfo ri = null;
3333            for (int i=0; ris != null && i<ris.size(); i++) {
3334                if ((ris.get(i).activityInfo.applicationInfo.flags
3335                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3336                    ri = ris.get(i);
3337                    break;
3338                }
3339            }
3340
3341            if (ri != null) {
3342                String vers = ri.activityInfo.metaData != null
3343                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3344                        : null;
3345                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3346                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3347                            Intent.METADATA_SETUP_VERSION);
3348                }
3349                String lastVers = Settings.Secure.getString(
3350                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3351                if (vers != null && !vers.equals(lastVers)) {
3352                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3353                    intent.setComponent(new ComponentName(
3354                            ri.activityInfo.packageName, ri.activityInfo.name));
3355                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3356                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3357                            null);
3358                }
3359            }
3360        }
3361    }
3362
3363    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3364        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3365    }
3366
3367    void enforceNotIsolatedCaller(String caller) {
3368        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3369            throw new SecurityException("Isolated process not allowed to call " + caller);
3370        }
3371    }
3372
3373    void enforceShellRestriction(String restriction, int userHandle) {
3374        if (Binder.getCallingUid() == Process.SHELL_UID) {
3375            if (userHandle < 0
3376                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3377                throw new SecurityException("Shell does not have permission to access user "
3378                        + userHandle);
3379            }
3380        }
3381    }
3382
3383    @Override
3384    public int getFrontActivityScreenCompatMode() {
3385        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3386        synchronized (this) {
3387            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3388        }
3389    }
3390
3391    @Override
3392    public void setFrontActivityScreenCompatMode(int mode) {
3393        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3394                "setFrontActivityScreenCompatMode");
3395        synchronized (this) {
3396            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3397        }
3398    }
3399
3400    @Override
3401    public int getPackageScreenCompatMode(String packageName) {
3402        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3403        synchronized (this) {
3404            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3405        }
3406    }
3407
3408    @Override
3409    public void setPackageScreenCompatMode(String packageName, int mode) {
3410        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3411                "setPackageScreenCompatMode");
3412        synchronized (this) {
3413            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3414        }
3415    }
3416
3417    @Override
3418    public boolean getPackageAskScreenCompat(String packageName) {
3419        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3420        synchronized (this) {
3421            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3422        }
3423    }
3424
3425    @Override
3426    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3427        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3428                "setPackageAskScreenCompat");
3429        synchronized (this) {
3430            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3431        }
3432    }
3433
3434    private void dispatchProcessesChanged() {
3435        int N;
3436        synchronized (this) {
3437            N = mPendingProcessChanges.size();
3438            if (mActiveProcessChanges.length < N) {
3439                mActiveProcessChanges = new ProcessChangeItem[N];
3440            }
3441            mPendingProcessChanges.toArray(mActiveProcessChanges);
3442            mAvailProcessChanges.addAll(mPendingProcessChanges);
3443            mPendingProcessChanges.clear();
3444            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3445        }
3446
3447        int i = mProcessObservers.beginBroadcast();
3448        while (i > 0) {
3449            i--;
3450            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3451            if (observer != null) {
3452                try {
3453                    for (int j=0; j<N; j++) {
3454                        ProcessChangeItem item = mActiveProcessChanges[j];
3455                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3456                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3457                                    + item.pid + " uid=" + item.uid + ": "
3458                                    + item.foregroundActivities);
3459                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3460                                    item.foregroundActivities);
3461                        }
3462                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3463                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3464                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3465                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3466                        }
3467                    }
3468                } catch (RemoteException e) {
3469                }
3470            }
3471        }
3472        mProcessObservers.finishBroadcast();
3473    }
3474
3475    private void dispatchProcessDied(int pid, int uid) {
3476        int i = mProcessObservers.beginBroadcast();
3477        while (i > 0) {
3478            i--;
3479            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3480            if (observer != null) {
3481                try {
3482                    observer.onProcessDied(pid, uid);
3483                } catch (RemoteException e) {
3484                }
3485            }
3486        }
3487        mProcessObservers.finishBroadcast();
3488    }
3489
3490    @Override
3491    public final int startActivity(IApplicationThread caller, String callingPackage,
3492            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3493            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3494        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3495            resultWho, requestCode, startFlags, profilerInfo, options,
3496            UserHandle.getCallingUserId());
3497    }
3498
3499    @Override
3500    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3501            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3502            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3503        enforceNotIsolatedCaller("startActivity");
3504        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3505                false, ALLOW_FULL_ONLY, "startActivity", null);
3506        // TODO: Switch to user app stacks here.
3507        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3508                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3509                profilerInfo, null, null, options, userId, null, null);
3510    }
3511
3512    @Override
3513    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3514            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3515            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3516
3517        // This is very dangerous -- it allows you to perform a start activity (including
3518        // permission grants) as any app that may launch one of your own activities.  So
3519        // we will only allow this to be done from activities that are part of the core framework,
3520        // and then only when they are running as the system.
3521        final ActivityRecord sourceRecord;
3522        final int targetUid;
3523        final String targetPackage;
3524        synchronized (this) {
3525            if (resultTo == null) {
3526                throw new SecurityException("Must be called from an activity");
3527            }
3528            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3529            if (sourceRecord == null) {
3530                throw new SecurityException("Called with bad activity token: " + resultTo);
3531            }
3532            if (!sourceRecord.info.packageName.equals("android")) {
3533                throw new SecurityException(
3534                        "Must be called from an activity that is declared in the android package");
3535            }
3536            if (sourceRecord.app == null) {
3537                throw new SecurityException("Called without a process attached to activity");
3538            }
3539            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3540                // This is still okay, as long as this activity is running under the
3541                // uid of the original calling activity.
3542                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3543                    throw new SecurityException(
3544                            "Calling activity in uid " + sourceRecord.app.uid
3545                                    + " must be system uid or original calling uid "
3546                                    + sourceRecord.launchedFromUid);
3547                }
3548            }
3549            targetUid = sourceRecord.launchedFromUid;
3550            targetPackage = sourceRecord.launchedFromPackage;
3551        }
3552
3553        // TODO: Switch to user app stacks here.
3554        try {
3555            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3556                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3557                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3558            return ret;
3559        } catch (SecurityException e) {
3560            // XXX need to figure out how to propagate to original app.
3561            // A SecurityException here is generally actually a fault of the original
3562            // calling activity (such as a fairly granting permissions), so propagate it
3563            // back to them.
3564            /*
3565            StringBuilder msg = new StringBuilder();
3566            msg.append("While launching");
3567            msg.append(intent.toString());
3568            msg.append(": ");
3569            msg.append(e.getMessage());
3570            */
3571            throw e;
3572        }
3573    }
3574
3575    @Override
3576    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3577            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3578            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3579        enforceNotIsolatedCaller("startActivityAndWait");
3580        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3581                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3582        WaitResult res = new WaitResult();
3583        // TODO: Switch to user app stacks here.
3584        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3585                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3586                options, userId, null, null);
3587        return res;
3588    }
3589
3590    @Override
3591    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3592            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3593            int startFlags, Configuration config, Bundle options, int userId) {
3594        enforceNotIsolatedCaller("startActivityWithConfig");
3595        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3596                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3597        // TODO: Switch to user app stacks here.
3598        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3599                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3600                null, null, config, options, userId, null, null);
3601        return ret;
3602    }
3603
3604    @Override
3605    public int startActivityIntentSender(IApplicationThread caller,
3606            IntentSender intent, Intent fillInIntent, String resolvedType,
3607            IBinder resultTo, String resultWho, int requestCode,
3608            int flagsMask, int flagsValues, Bundle options) {
3609        enforceNotIsolatedCaller("startActivityIntentSender");
3610        // Refuse possible leaked file descriptors
3611        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3612            throw new IllegalArgumentException("File descriptors passed in Intent");
3613        }
3614
3615        IIntentSender sender = intent.getTarget();
3616        if (!(sender instanceof PendingIntentRecord)) {
3617            throw new IllegalArgumentException("Bad PendingIntent object");
3618        }
3619
3620        PendingIntentRecord pir = (PendingIntentRecord)sender;
3621
3622        synchronized (this) {
3623            // If this is coming from the currently resumed activity, it is
3624            // effectively saying that app switches are allowed at this point.
3625            final ActivityStack stack = getFocusedStack();
3626            if (stack.mResumedActivity != null &&
3627                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3628                mAppSwitchesAllowedTime = 0;
3629            }
3630        }
3631        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3632                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3633        return ret;
3634    }
3635
3636    @Override
3637    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3638            Intent intent, String resolvedType, IVoiceInteractionSession session,
3639            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3640            Bundle options, int userId) {
3641        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3642                != PackageManager.PERMISSION_GRANTED) {
3643            String msg = "Permission Denial: startVoiceActivity() from pid="
3644                    + Binder.getCallingPid()
3645                    + ", uid=" + Binder.getCallingUid()
3646                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3647            Slog.w(TAG, msg);
3648            throw new SecurityException(msg);
3649        }
3650        if (session == null || interactor == null) {
3651            throw new NullPointerException("null session or interactor");
3652        }
3653        userId = handleIncomingUser(callingPid, callingUid, userId,
3654                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3655        // TODO: Switch to user app stacks here.
3656        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3657                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3658                null, options, userId, null, null);
3659    }
3660
3661    @Override
3662    public boolean startNextMatchingActivity(IBinder callingActivity,
3663            Intent intent, Bundle options) {
3664        // Refuse possible leaked file descriptors
3665        if (intent != null && intent.hasFileDescriptors() == true) {
3666            throw new IllegalArgumentException("File descriptors passed in Intent");
3667        }
3668
3669        synchronized (this) {
3670            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3671            if (r == null) {
3672                ActivityOptions.abort(options);
3673                return false;
3674            }
3675            if (r.app == null || r.app.thread == null) {
3676                // The caller is not running...  d'oh!
3677                ActivityOptions.abort(options);
3678                return false;
3679            }
3680            intent = new Intent(intent);
3681            // The caller is not allowed to change the data.
3682            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3683            // And we are resetting to find the next component...
3684            intent.setComponent(null);
3685
3686            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3687
3688            ActivityInfo aInfo = null;
3689            try {
3690                List<ResolveInfo> resolves =
3691                    AppGlobals.getPackageManager().queryIntentActivities(
3692                            intent, r.resolvedType,
3693                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3694                            UserHandle.getCallingUserId());
3695
3696                // Look for the original activity in the list...
3697                final int N = resolves != null ? resolves.size() : 0;
3698                for (int i=0; i<N; i++) {
3699                    ResolveInfo rInfo = resolves.get(i);
3700                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3701                            && rInfo.activityInfo.name.equals(r.info.name)) {
3702                        // We found the current one...  the next matching is
3703                        // after it.
3704                        i++;
3705                        if (i<N) {
3706                            aInfo = resolves.get(i).activityInfo;
3707                        }
3708                        if (debug) {
3709                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3710                                    + "/" + r.info.name);
3711                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3712                                    + "/" + aInfo.name);
3713                        }
3714                        break;
3715                    }
3716                }
3717            } catch (RemoteException e) {
3718            }
3719
3720            if (aInfo == null) {
3721                // Nobody who is next!
3722                ActivityOptions.abort(options);
3723                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3724                return false;
3725            }
3726
3727            intent.setComponent(new ComponentName(
3728                    aInfo.applicationInfo.packageName, aInfo.name));
3729            intent.setFlags(intent.getFlags()&~(
3730                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3731                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3732                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3733                    Intent.FLAG_ACTIVITY_NEW_TASK));
3734
3735            // Okay now we need to start the new activity, replacing the
3736            // currently running activity.  This is a little tricky because
3737            // we want to start the new one as if the current one is finished,
3738            // but not finish the current one first so that there is no flicker.
3739            // And thus...
3740            final boolean wasFinishing = r.finishing;
3741            r.finishing = true;
3742
3743            // Propagate reply information over to the new activity.
3744            final ActivityRecord resultTo = r.resultTo;
3745            final String resultWho = r.resultWho;
3746            final int requestCode = r.requestCode;
3747            r.resultTo = null;
3748            if (resultTo != null) {
3749                resultTo.removeResultsLocked(r, resultWho, requestCode);
3750            }
3751
3752            final long origId = Binder.clearCallingIdentity();
3753            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3754                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3755                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3756                    options, false, null, null, null);
3757            Binder.restoreCallingIdentity(origId);
3758
3759            r.finishing = wasFinishing;
3760            if (res != ActivityManager.START_SUCCESS) {
3761                return false;
3762            }
3763            return true;
3764        }
3765    }
3766
3767    @Override
3768    public final int startActivityFromRecents(int taskId, Bundle options) {
3769        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3770            String msg = "Permission Denial: startActivityFromRecents called without " +
3771                    START_TASKS_FROM_RECENTS;
3772            Slog.w(TAG, msg);
3773            throw new SecurityException(msg);
3774        }
3775        return startActivityFromRecentsInner(taskId, options);
3776    }
3777
3778    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3779        final TaskRecord task;
3780        final int callingUid;
3781        final String callingPackage;
3782        final Intent intent;
3783        final int userId;
3784        synchronized (this) {
3785            task = recentTaskForIdLocked(taskId);
3786            if (task == null) {
3787                throw new IllegalArgumentException("Task " + taskId + " not found.");
3788            }
3789            callingUid = task.mCallingUid;
3790            callingPackage = task.mCallingPackage;
3791            intent = task.intent;
3792            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3793            userId = task.userId;
3794        }
3795        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3796                options, userId, null, task);
3797    }
3798
3799    final int startActivityInPackage(int uid, String callingPackage,
3800            Intent intent, String resolvedType, IBinder resultTo,
3801            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3802            IActivityContainer container, TaskRecord inTask) {
3803
3804        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3805                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3806
3807        // TODO: Switch to user app stacks here.
3808        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3809                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3810                null, null, null, options, userId, container, inTask);
3811        return ret;
3812    }
3813
3814    @Override
3815    public final int startActivities(IApplicationThread caller, String callingPackage,
3816            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3817            int userId) {
3818        enforceNotIsolatedCaller("startActivities");
3819        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3820                false, ALLOW_FULL_ONLY, "startActivity", null);
3821        // TODO: Switch to user app stacks here.
3822        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3823                resolvedTypes, resultTo, options, userId);
3824        return ret;
3825    }
3826
3827    final int startActivitiesInPackage(int uid, String callingPackage,
3828            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3829            Bundle options, int userId) {
3830
3831        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3832                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3833        // TODO: Switch to user app stacks here.
3834        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3835                resultTo, options, userId);
3836        return ret;
3837    }
3838
3839    //explicitly remove thd old information in mRecentTasks when removing existing user.
3840    private void removeRecentTasksForUserLocked(int userId) {
3841        if(userId <= 0) {
3842            Slog.i(TAG, "Can't remove recent task on user " + userId);
3843            return;
3844        }
3845
3846        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3847            TaskRecord tr = mRecentTasks.get(i);
3848            if (tr.userId == userId) {
3849                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3850                        + " when finishing user" + userId);
3851                mRecentTasks.remove(i);
3852                tr.removedFromRecents(mTaskPersister);
3853            }
3854        }
3855
3856        // Remove tasks from persistent storage.
3857        mTaskPersister.wakeup(null, true);
3858    }
3859
3860    /**
3861     * Update the recent tasks lists: make sure tasks should still be here (their
3862     * applications / activities still exist), update their availability, fixup ordering
3863     * of affiliations.
3864     */
3865    void cleanupRecentTasksLocked(int userId) {
3866        if (mRecentTasks == null) {
3867            // Happens when called from the packagemanager broadcast before boot.
3868            return;
3869        }
3870
3871        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3872        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3873        final IPackageManager pm = AppGlobals.getPackageManager();
3874        final ActivityInfo dummyAct = new ActivityInfo();
3875        final ApplicationInfo dummyApp = new ApplicationInfo();
3876
3877        int N = mRecentTasks.size();
3878
3879        int[] users = userId == UserHandle.USER_ALL
3880                ? getUsersLocked() : new int[] { userId };
3881        for (int user : users) {
3882            for (int i = 0; i < N; i++) {
3883                TaskRecord task = mRecentTasks.get(i);
3884                if (task.userId != user) {
3885                    // Only look at tasks for the user ID of interest.
3886                    continue;
3887                }
3888                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3889                    // This situation is broken, and we should just get rid of it now.
3890                    mRecentTasks.remove(i);
3891                    task.removedFromRecents(mTaskPersister);
3892                    i--;
3893                    N--;
3894                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3895                    continue;
3896                }
3897                // Check whether this activity is currently available.
3898                if (task.realActivity != null) {
3899                    ActivityInfo ai = availActCache.get(task.realActivity);
3900                    if (ai == null) {
3901                        try {
3902                            ai = pm.getActivityInfo(task.realActivity,
3903                                    PackageManager.GET_UNINSTALLED_PACKAGES
3904                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3905                        } catch (RemoteException e) {
3906                            // Will never happen.
3907                            continue;
3908                        }
3909                        if (ai == null) {
3910                            ai = dummyAct;
3911                        }
3912                        availActCache.put(task.realActivity, ai);
3913                    }
3914                    if (ai == dummyAct) {
3915                        // This could be either because the activity no longer exists, or the
3916                        // app is temporarily gone.  For the former we want to remove the recents
3917                        // entry; for the latter we want to mark it as unavailable.
3918                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3919                        if (app == null) {
3920                            try {
3921                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3922                                        PackageManager.GET_UNINSTALLED_PACKAGES
3923                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3924                            } catch (RemoteException e) {
3925                                // Will never happen.
3926                                continue;
3927                            }
3928                            if (app == null) {
3929                                app = dummyApp;
3930                            }
3931                            availAppCache.put(task.realActivity.getPackageName(), app);
3932                        }
3933                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3934                            // Doesn't exist any more!  Good-bye.
3935                            mRecentTasks.remove(i);
3936                            task.removedFromRecents(mTaskPersister);
3937                            i--;
3938                            N--;
3939                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3940                            continue;
3941                        } else {
3942                            // Otherwise just not available for now.
3943                            if (task.isAvailable) {
3944                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3945                                        + task);
3946                            }
3947                            task.isAvailable = false;
3948                        }
3949                    } else {
3950                        if (!ai.enabled || !ai.applicationInfo.enabled
3951                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3952                            if (task.isAvailable) {
3953                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3954                                        + task + " (enabled=" + ai.enabled + "/"
3955                                        + ai.applicationInfo.enabled +  " flags="
3956                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3957                            }
3958                            task.isAvailable = false;
3959                        } else {
3960                            if (!task.isAvailable) {
3961                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3962                                        + task);
3963                            }
3964                            task.isAvailable = true;
3965                        }
3966                    }
3967                }
3968            }
3969        }
3970
3971        // Verify the affiliate chain for each task.
3972        for (int i = 0; i < N; ) {
3973            TaskRecord task = mRecentTasks.remove(i);
3974            if (mTmpRecents.contains(task)) {
3975                continue;
3976            }
3977            int affiliatedTaskId = task.mAffiliatedTaskId;
3978            while (true) {
3979                TaskRecord next = task.mNextAffiliate;
3980                if (next == null) {
3981                    break;
3982                }
3983                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3984                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3985                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3986                    task.setNextAffiliate(null);
3987                    if (next.mPrevAffiliate == task) {
3988                        next.setPrevAffiliate(null);
3989                    }
3990                    break;
3991                }
3992                if (next.mPrevAffiliate != task) {
3993                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3994                            next.mPrevAffiliate + " task=" + task);
3995                    next.setPrevAffiliate(null);
3996                    task.setNextAffiliate(null);
3997                    break;
3998                }
3999                if (!mRecentTasks.contains(next)) {
4000                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
4001                    task.setNextAffiliate(null);
4002                    // We know that next.mPrevAffiliate is always task, from above, so clear
4003                    // its previous affiliate.
4004                    next.setPrevAffiliate(null);
4005                    break;
4006                }
4007                task = next;
4008            }
4009            // task is now the end of the list
4010            do {
4011                mRecentTasks.remove(task);
4012                mRecentTasks.add(i++, task);
4013                mTmpRecents.add(task);
4014                task.inRecents = true;
4015            } while ((task = task.mPrevAffiliate) != null);
4016        }
4017        mTmpRecents.clear();
4018        // mRecentTasks is now in sorted, affiliated order.
4019    }
4020
4021    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4022        int N = mRecentTasks.size();
4023        TaskRecord top = task;
4024        int topIndex = taskIndex;
4025        while (top.mNextAffiliate != null && topIndex > 0) {
4026            top = top.mNextAffiliate;
4027            topIndex--;
4028        }
4029        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4030                + topIndex + " from intial " + taskIndex);
4031        // Find the end of the chain, doing a sanity check along the way.
4032        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4033        int endIndex = topIndex;
4034        TaskRecord prev = top;
4035        while (endIndex < N) {
4036            TaskRecord cur = mRecentTasks.get(endIndex);
4037            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4038                    + endIndex + " " + cur);
4039            if (cur == top) {
4040                // Verify start of the chain.
4041                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4042                    Slog.wtf(TAG, "Bad chain @" + endIndex
4043                            + ": first task has next affiliate: " + prev);
4044                    sane = false;
4045                    break;
4046                }
4047            } else {
4048                // Verify middle of the chain's next points back to the one before.
4049                if (cur.mNextAffiliate != prev
4050                        || cur.mNextAffiliateTaskId != prev.taskId) {
4051                    Slog.wtf(TAG, "Bad chain @" + endIndex
4052                            + ": middle task " + cur + " @" + endIndex
4053                            + " has bad next affiliate "
4054                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4055                            + ", expected " + prev);
4056                    sane = false;
4057                    break;
4058                }
4059            }
4060            if (cur.mPrevAffiliateTaskId == -1) {
4061                // Chain ends here.
4062                if (cur.mPrevAffiliate != null) {
4063                    Slog.wtf(TAG, "Bad chain @" + endIndex
4064                            + ": last task " + cur + " has previous affiliate "
4065                            + cur.mPrevAffiliate);
4066                    sane = false;
4067                }
4068                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4069                break;
4070            } else {
4071                // Verify middle of the chain's prev points to a valid item.
4072                if (cur.mPrevAffiliate == null) {
4073                    Slog.wtf(TAG, "Bad chain @" + endIndex
4074                            + ": task " + cur + " has previous affiliate "
4075                            + cur.mPrevAffiliate + " but should be id "
4076                            + cur.mPrevAffiliate);
4077                    sane = false;
4078                    break;
4079                }
4080            }
4081            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4082                Slog.wtf(TAG, "Bad chain @" + endIndex
4083                        + ": task " + cur + " has affiliated id "
4084                        + cur.mAffiliatedTaskId + " but should be "
4085                        + task.mAffiliatedTaskId);
4086                sane = false;
4087                break;
4088            }
4089            prev = cur;
4090            endIndex++;
4091            if (endIndex >= N) {
4092                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4093                        + ": last task " + prev);
4094                sane = false;
4095                break;
4096            }
4097        }
4098        if (sane) {
4099            if (endIndex < taskIndex) {
4100                Slog.wtf(TAG, "Bad chain @" + endIndex
4101                        + ": did not extend to task " + task + " @" + taskIndex);
4102                sane = false;
4103            }
4104        }
4105        if (sane) {
4106            // All looks good, we can just move all of the affiliated tasks
4107            // to the top.
4108            for (int i=topIndex; i<=endIndex; i++) {
4109                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4110                        + " from " + i + " to " + (i-topIndex));
4111                TaskRecord cur = mRecentTasks.remove(i);
4112                mRecentTasks.add(i-topIndex, cur);
4113            }
4114            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4115                    + " to " + endIndex);
4116            return true;
4117        }
4118
4119        // Whoops, couldn't do it.
4120        return false;
4121    }
4122
4123    final void addRecentTaskLocked(TaskRecord task) {
4124        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4125                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4126
4127        int N = mRecentTasks.size();
4128        // Quick case: check if the top-most recent task is the same.
4129        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4130            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4131            return;
4132        }
4133        // Another quick case: check if this is part of a set of affiliated
4134        // tasks that are at the top.
4135        if (isAffiliated && N > 0 && task.inRecents
4136                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4137            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4138                    + " at top when adding " + task);
4139            return;
4140        }
4141        // Another quick case: never add voice sessions.
4142        if (task.voiceSession != null) {
4143            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4144            return;
4145        }
4146
4147        boolean needAffiliationFix = false;
4148
4149        // Slightly less quick case: the task is already in recents, so all we need
4150        // to do is move it.
4151        if (task.inRecents) {
4152            int taskIndex = mRecentTasks.indexOf(task);
4153            if (taskIndex >= 0) {
4154                if (!isAffiliated) {
4155                    // Simple case: this is not an affiliated task, so we just move it to the front.
4156                    mRecentTasks.remove(taskIndex);
4157                    mRecentTasks.add(0, task);
4158                    notifyTaskPersisterLocked(task, false);
4159                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4160                            + " from " + taskIndex);
4161                    return;
4162                } else {
4163                    // More complicated: need to keep all affiliated tasks together.
4164                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4165                        // All went well.
4166                        return;
4167                    }
4168
4169                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4170                    // everything and then go through our general path of adding a new task.
4171                    needAffiliationFix = true;
4172                }
4173            } else {
4174                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4175                needAffiliationFix = true;
4176            }
4177        }
4178
4179        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4180        trimRecentsForTask(task, true);
4181
4182        N = mRecentTasks.size();
4183        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4184            final TaskRecord tr = mRecentTasks.remove(N - 1);
4185            tr.removedFromRecents(mTaskPersister);
4186            N--;
4187        }
4188        task.inRecents = true;
4189        if (!isAffiliated || needAffiliationFix) {
4190            // If this is a simple non-affiliated task, or we had some failure trying to
4191            // handle it as part of an affilated task, then just place it at the top.
4192            mRecentTasks.add(0, task);
4193        } else if (isAffiliated) {
4194            // If this is a new affiliated task, then move all of the affiliated tasks
4195            // to the front and insert this new one.
4196            TaskRecord other = task.mNextAffiliate;
4197            if (other == null) {
4198                other = task.mPrevAffiliate;
4199            }
4200            if (other != null) {
4201                int otherIndex = mRecentTasks.indexOf(other);
4202                if (otherIndex >= 0) {
4203                    // Insert new task at appropriate location.
4204                    int taskIndex;
4205                    if (other == task.mNextAffiliate) {
4206                        // We found the index of our next affiliation, which is who is
4207                        // before us in the list, so add after that point.
4208                        taskIndex = otherIndex+1;
4209                    } else {
4210                        // We found the index of our previous affiliation, which is who is
4211                        // after us in the list, so add at their position.
4212                        taskIndex = otherIndex;
4213                    }
4214                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4215                            + taskIndex + ": " + task);
4216                    mRecentTasks.add(taskIndex, task);
4217
4218                    // Now move everything to the front.
4219                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4220                        // All went well.
4221                        return;
4222                    }
4223
4224                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4225                    // everything and then go through our general path of adding a new task.
4226                    needAffiliationFix = true;
4227                } else {
4228                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4229                            + other);
4230                    needAffiliationFix = true;
4231                }
4232            } else {
4233                if (DEBUG_RECENTS) Slog.d(TAG,
4234                        "addRecent: adding affiliated task without next/prev:" + task);
4235                needAffiliationFix = true;
4236            }
4237        }
4238        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4239
4240        if (needAffiliationFix) {
4241            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4242            cleanupRecentTasksLocked(task.userId);
4243        }
4244    }
4245
4246    /**
4247     * If needed, remove oldest existing entries in recents that are for the same kind
4248     * of task as the given one.
4249     */
4250    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4251        int N = mRecentTasks.size();
4252        final Intent intent = task.intent;
4253        final boolean document = intent != null && intent.isDocument();
4254
4255        int maxRecents = task.maxRecents - 1;
4256        for (int i=0; i<N; i++) {
4257            final TaskRecord tr = mRecentTasks.get(i);
4258            if (task != tr) {
4259                if (task.userId != tr.userId) {
4260                    continue;
4261                }
4262                if (i > MAX_RECENT_BITMAPS) {
4263                    tr.freeLastThumbnail();
4264                }
4265                final Intent trIntent = tr.intent;
4266                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4267                    (intent == null || !intent.filterEquals(trIntent))) {
4268                    continue;
4269                }
4270                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4271                if (document && trIsDocument) {
4272                    // These are the same document activity (not necessarily the same doc).
4273                    if (maxRecents > 0) {
4274                        --maxRecents;
4275                        continue;
4276                    }
4277                    // Hit the maximum number of documents for this task. Fall through
4278                    // and remove this document from recents.
4279                } else if (document || trIsDocument) {
4280                    // Only one of these is a document. Not the droid we're looking for.
4281                    continue;
4282                }
4283            }
4284
4285            if (!doTrim) {
4286                // If the caller is not actually asking for a trim, just tell them we reached
4287                // a point where the trim would happen.
4288                return i;
4289            }
4290
4291            // Either task and tr are the same or, their affinities match or their intents match
4292            // and neither of them is a document, or they are documents using the same activity
4293            // and their maxRecents has been reached.
4294            tr.disposeThumbnail();
4295            mRecentTasks.remove(i);
4296            if (task != tr) {
4297                tr.removedFromRecents(mTaskPersister);
4298            }
4299            i--;
4300            N--;
4301            if (task.intent == null) {
4302                // If the new recent task we are adding is not fully
4303                // specified, then replace it with the existing recent task.
4304                task = tr;
4305            }
4306            notifyTaskPersisterLocked(tr, false);
4307        }
4308
4309        return -1;
4310    }
4311
4312    @Override
4313    public void reportActivityFullyDrawn(IBinder token) {
4314        synchronized (this) {
4315            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4316            if (r == null) {
4317                return;
4318            }
4319            r.reportFullyDrawnLocked();
4320        }
4321    }
4322
4323    @Override
4324    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4325        synchronized (this) {
4326            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4327            if (r == null) {
4328                return;
4329            }
4330            final long origId = Binder.clearCallingIdentity();
4331            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4332            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4333                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4334            if (config != null) {
4335                r.frozenBeforeDestroy = true;
4336                if (!updateConfigurationLocked(config, r, false, false)) {
4337                    mStackSupervisor.resumeTopActivitiesLocked();
4338                }
4339            }
4340            Binder.restoreCallingIdentity(origId);
4341        }
4342    }
4343
4344    @Override
4345    public int getRequestedOrientation(IBinder token) {
4346        synchronized (this) {
4347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4348            if (r == null) {
4349                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4350            }
4351            return mWindowManager.getAppOrientation(r.appToken);
4352        }
4353    }
4354
4355    /**
4356     * This is the internal entry point for handling Activity.finish().
4357     *
4358     * @param token The Binder token referencing the Activity we want to finish.
4359     * @param resultCode Result code, if any, from this Activity.
4360     * @param resultData Result data (Intent), if any, from this Activity.
4361     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4362     *            the root Activity in the task.
4363     *
4364     * @return Returns true if the activity successfully finished, or false if it is still running.
4365     */
4366    @Override
4367    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4368            boolean finishTask) {
4369        // Refuse possible leaked file descriptors
4370        if (resultData != null && resultData.hasFileDescriptors() == true) {
4371            throw new IllegalArgumentException("File descriptors passed in Intent");
4372        }
4373
4374        synchronized(this) {
4375            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4376            if (r == null) {
4377                return true;
4378            }
4379            // Keep track of the root activity of the task before we finish it
4380            TaskRecord tr = r.task;
4381            ActivityRecord rootR = tr.getRootActivity();
4382            // Do not allow task to finish in Lock Task mode.
4383            if (tr == mStackSupervisor.mLockTaskModeTask) {
4384                if (rootR == r) {
4385                    mStackSupervisor.showLockTaskToast();
4386                    return false;
4387                }
4388            }
4389            if (mController != null) {
4390                // Find the first activity that is not finishing.
4391                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4392                if (next != null) {
4393                    // ask watcher if this is allowed
4394                    boolean resumeOK = true;
4395                    try {
4396                        resumeOK = mController.activityResuming(next.packageName);
4397                    } catch (RemoteException e) {
4398                        mController = null;
4399                        Watchdog.getInstance().setActivityController(null);
4400                    }
4401
4402                    if (!resumeOK) {
4403                        return false;
4404                    }
4405                }
4406            }
4407            final long origId = Binder.clearCallingIdentity();
4408            try {
4409                boolean res;
4410                if (finishTask && r == rootR) {
4411                    // If requested, remove the task that is associated to this activity only if it
4412                    // was the root activity in the task.  The result code and data is ignored because
4413                    // we don't support returning them across task boundaries.
4414                    res = removeTaskByIdLocked(tr.taskId, 0);
4415                } else {
4416                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4417                            resultData, "app-request", true);
4418                }
4419                return res;
4420            } finally {
4421                Binder.restoreCallingIdentity(origId);
4422            }
4423        }
4424    }
4425
4426    @Override
4427    public final void finishHeavyWeightApp() {
4428        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4429                != PackageManager.PERMISSION_GRANTED) {
4430            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4431                    + Binder.getCallingPid()
4432                    + ", uid=" + Binder.getCallingUid()
4433                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4434            Slog.w(TAG, msg);
4435            throw new SecurityException(msg);
4436        }
4437
4438        synchronized(this) {
4439            if (mHeavyWeightProcess == null) {
4440                return;
4441            }
4442
4443            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4444                    mHeavyWeightProcess.activities);
4445            for (int i=0; i<activities.size(); i++) {
4446                ActivityRecord r = activities.get(i);
4447                if (!r.finishing) {
4448                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4449                            null, "finish-heavy", true);
4450                }
4451            }
4452
4453            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4454                    mHeavyWeightProcess.userId, 0));
4455            mHeavyWeightProcess = null;
4456        }
4457    }
4458
4459    @Override
4460    public void crashApplication(int uid, int initialPid, String packageName,
4461            String message) {
4462        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4463                != PackageManager.PERMISSION_GRANTED) {
4464            String msg = "Permission Denial: crashApplication() from pid="
4465                    + Binder.getCallingPid()
4466                    + ", uid=" + Binder.getCallingUid()
4467                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4468            Slog.w(TAG, msg);
4469            throw new SecurityException(msg);
4470        }
4471
4472        synchronized(this) {
4473            ProcessRecord proc = null;
4474
4475            // Figure out which process to kill.  We don't trust that initialPid
4476            // still has any relation to current pids, so must scan through the
4477            // list.
4478            synchronized (mPidsSelfLocked) {
4479                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4480                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4481                    if (p.uid != uid) {
4482                        continue;
4483                    }
4484                    if (p.pid == initialPid) {
4485                        proc = p;
4486                        break;
4487                    }
4488                    if (p.pkgList.containsKey(packageName)) {
4489                        proc = p;
4490                    }
4491                }
4492            }
4493
4494            if (proc == null) {
4495                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4496                        + " initialPid=" + initialPid
4497                        + " packageName=" + packageName);
4498                return;
4499            }
4500
4501            if (proc.thread != null) {
4502                if (proc.pid == Process.myPid()) {
4503                    Log.w(TAG, "crashApplication: trying to crash self!");
4504                    return;
4505                }
4506                long ident = Binder.clearCallingIdentity();
4507                try {
4508                    proc.thread.scheduleCrash(message);
4509                } catch (RemoteException e) {
4510                }
4511                Binder.restoreCallingIdentity(ident);
4512            }
4513        }
4514    }
4515
4516    @Override
4517    public final void finishSubActivity(IBinder token, String resultWho,
4518            int requestCode) {
4519        synchronized(this) {
4520            final long origId = Binder.clearCallingIdentity();
4521            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4522            if (r != null) {
4523                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4524            }
4525            Binder.restoreCallingIdentity(origId);
4526        }
4527    }
4528
4529    @Override
4530    public boolean finishActivityAffinity(IBinder token) {
4531        synchronized(this) {
4532            final long origId = Binder.clearCallingIdentity();
4533            try {
4534                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4535
4536                ActivityRecord rootR = r.task.getRootActivity();
4537                // Do not allow task to finish in Lock Task mode.
4538                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4539                    if (rootR == r) {
4540                        mStackSupervisor.showLockTaskToast();
4541                        return false;
4542                    }
4543                }
4544                boolean res = false;
4545                if (r != null) {
4546                    res = r.task.stack.finishActivityAffinityLocked(r);
4547                }
4548                return res;
4549            } finally {
4550                Binder.restoreCallingIdentity(origId);
4551            }
4552        }
4553    }
4554
4555    @Override
4556    public void finishVoiceTask(IVoiceInteractionSession session) {
4557        synchronized(this) {
4558            final long origId = Binder.clearCallingIdentity();
4559            try {
4560                mStackSupervisor.finishVoiceTask(session);
4561            } finally {
4562                Binder.restoreCallingIdentity(origId);
4563            }
4564        }
4565
4566    }
4567
4568    @Override
4569    public boolean releaseActivityInstance(IBinder token) {
4570        synchronized(this) {
4571            final long origId = Binder.clearCallingIdentity();
4572            try {
4573                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4574                if (r.task == null || r.task.stack == null) {
4575                    return false;
4576                }
4577                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4578            } finally {
4579                Binder.restoreCallingIdentity(origId);
4580            }
4581        }
4582    }
4583
4584    @Override
4585    public void releaseSomeActivities(IApplicationThread appInt) {
4586        synchronized(this) {
4587            final long origId = Binder.clearCallingIdentity();
4588            try {
4589                ProcessRecord app = getRecordForAppLocked(appInt);
4590                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4591            } finally {
4592                Binder.restoreCallingIdentity(origId);
4593            }
4594        }
4595    }
4596
4597    @Override
4598    public boolean willActivityBeVisible(IBinder token) {
4599        synchronized(this) {
4600            ActivityStack stack = ActivityRecord.getStackLocked(token);
4601            if (stack != null) {
4602                return stack.willActivityBeVisibleLocked(token);
4603            }
4604            return false;
4605        }
4606    }
4607
4608    @Override
4609    public void overridePendingTransition(IBinder token, String packageName,
4610            int enterAnim, int exitAnim) {
4611        synchronized(this) {
4612            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4613            if (self == null) {
4614                return;
4615            }
4616
4617            final long origId = Binder.clearCallingIdentity();
4618
4619            if (self.state == ActivityState.RESUMED
4620                    || self.state == ActivityState.PAUSING) {
4621                mWindowManager.overridePendingAppTransition(packageName,
4622                        enterAnim, exitAnim, null);
4623            }
4624
4625            Binder.restoreCallingIdentity(origId);
4626        }
4627    }
4628
4629    /**
4630     * Main function for removing an existing process from the activity manager
4631     * as a result of that process going away.  Clears out all connections
4632     * to the process.
4633     */
4634    private final void handleAppDiedLocked(ProcessRecord app,
4635            boolean restarting, boolean allowRestart) {
4636        int pid = app.pid;
4637        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4638        if (!restarting) {
4639            removeLruProcessLocked(app);
4640            if (pid > 0) {
4641                ProcessList.remove(pid);
4642            }
4643        }
4644
4645        if (mProfileProc == app) {
4646            clearProfilerLocked();
4647        }
4648
4649        // Remove this application's activities from active lists.
4650        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4651
4652        app.activities.clear();
4653
4654        if (app.instrumentationClass != null) {
4655            Slog.w(TAG, "Crash of app " + app.processName
4656                  + " running instrumentation " + app.instrumentationClass);
4657            Bundle info = new Bundle();
4658            info.putString("shortMsg", "Process crashed.");
4659            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4660        }
4661
4662        if (!restarting) {
4663            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4664                // If there was nothing to resume, and we are not already
4665                // restarting this process, but there is a visible activity that
4666                // is hosted by the process...  then make sure all visible
4667                // activities are running, taking care of restarting this
4668                // process.
4669                if (hasVisibleActivities) {
4670                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4671                }
4672            }
4673        }
4674    }
4675
4676    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4677        IBinder threadBinder = thread.asBinder();
4678        // Find the application record.
4679        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4680            ProcessRecord rec = mLruProcesses.get(i);
4681            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4682                return i;
4683            }
4684        }
4685        return -1;
4686    }
4687
4688    final ProcessRecord getRecordForAppLocked(
4689            IApplicationThread thread) {
4690        if (thread == null) {
4691            return null;
4692        }
4693
4694        int appIndex = getLRURecordIndexForAppLocked(thread);
4695        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4696    }
4697
4698    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4699        // If there are no longer any background processes running,
4700        // and the app that died was not running instrumentation,
4701        // then tell everyone we are now low on memory.
4702        boolean haveBg = false;
4703        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4704            ProcessRecord rec = mLruProcesses.get(i);
4705            if (rec.thread != null
4706                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4707                haveBg = true;
4708                break;
4709            }
4710        }
4711
4712        if (!haveBg) {
4713            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4714            if (doReport) {
4715                long now = SystemClock.uptimeMillis();
4716                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4717                    doReport = false;
4718                } else {
4719                    mLastMemUsageReportTime = now;
4720                }
4721            }
4722            final ArrayList<ProcessMemInfo> memInfos
4723                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4724            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4725            long now = SystemClock.uptimeMillis();
4726            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4727                ProcessRecord rec = mLruProcesses.get(i);
4728                if (rec == dyingProc || rec.thread == null) {
4729                    continue;
4730                }
4731                if (doReport) {
4732                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4733                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4734                }
4735                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4736                    // The low memory report is overriding any current
4737                    // state for a GC request.  Make sure to do
4738                    // heavy/important/visible/foreground processes first.
4739                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4740                        rec.lastRequestedGc = 0;
4741                    } else {
4742                        rec.lastRequestedGc = rec.lastLowMemory;
4743                    }
4744                    rec.reportLowMemory = true;
4745                    rec.lastLowMemory = now;
4746                    mProcessesToGc.remove(rec);
4747                    addProcessToGcListLocked(rec);
4748                }
4749            }
4750            if (doReport) {
4751                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4752                mHandler.sendMessage(msg);
4753            }
4754            scheduleAppGcsLocked();
4755        }
4756    }
4757
4758    final void appDiedLocked(ProcessRecord app) {
4759       appDiedLocked(app, app.pid, app.thread);
4760    }
4761
4762    final void appDiedLocked(ProcessRecord app, int pid,
4763            IApplicationThread thread) {
4764
4765        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4766        synchronized (stats) {
4767            stats.noteProcessDiedLocked(app.info.uid, pid);
4768        }
4769
4770        Process.killProcessGroup(app.info.uid, pid);
4771
4772        // Clean up already done if the process has been re-started.
4773        if (app.pid == pid && app.thread != null &&
4774                app.thread.asBinder() == thread.asBinder()) {
4775            boolean doLowMem = app.instrumentationClass == null;
4776            boolean doOomAdj = doLowMem;
4777            if (!app.killedByAm) {
4778                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4779                        + ") has died.");
4780                mAllowLowerMemLevel = true;
4781            } else {
4782                // Note that we always want to do oom adj to update our state with the
4783                // new number of procs.
4784                mAllowLowerMemLevel = false;
4785                doLowMem = false;
4786            }
4787            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4788            if (DEBUG_CLEANUP) Slog.v(
4789                TAG, "Dying app: " + app + ", pid: " + pid
4790                + ", thread: " + thread.asBinder());
4791            handleAppDiedLocked(app, false, true);
4792
4793            if (doOomAdj) {
4794                updateOomAdjLocked();
4795            }
4796            if (doLowMem) {
4797                doLowMemReportIfNeededLocked(app);
4798            }
4799        } else if (app.pid != pid) {
4800            // A new process has already been started.
4801            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4802                    + ") has died and restarted (pid " + app.pid + ").");
4803            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4804        } else if (DEBUG_PROCESSES) {
4805            Slog.d(TAG, "Received spurious death notification for thread "
4806                    + thread.asBinder());
4807        }
4808    }
4809
4810    /**
4811     * If a stack trace dump file is configured, dump process stack traces.
4812     * @param clearTraces causes the dump file to be erased prior to the new
4813     *    traces being written, if true; when false, the new traces will be
4814     *    appended to any existing file content.
4815     * @param firstPids of dalvik VM processes to dump stack traces for first
4816     * @param lastPids of dalvik VM processes to dump stack traces for last
4817     * @param nativeProcs optional list of native process names to dump stack crawls
4818     * @return file containing stack traces, or null if no dump file is configured
4819     */
4820    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4821            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4822        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4823        if (tracesPath == null || tracesPath.length() == 0) {
4824            return null;
4825        }
4826
4827        File tracesFile = new File(tracesPath);
4828        try {
4829            File tracesDir = tracesFile.getParentFile();
4830            if (!tracesDir.exists()) {
4831                tracesFile.mkdirs();
4832                if (!SELinux.restorecon(tracesDir)) {
4833                    return null;
4834                }
4835            }
4836            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4837
4838            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4839            tracesFile.createNewFile();
4840            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4841        } catch (IOException e) {
4842            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4843            return null;
4844        }
4845
4846        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4847        return tracesFile;
4848    }
4849
4850    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4851            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4852        // Use a FileObserver to detect when traces finish writing.
4853        // The order of traces is considered important to maintain for legibility.
4854        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4855            @Override
4856            public synchronized void onEvent(int event, String path) { notify(); }
4857        };
4858
4859        try {
4860            observer.startWatching();
4861
4862            // First collect all of the stacks of the most important pids.
4863            if (firstPids != null) {
4864                try {
4865                    int num = firstPids.size();
4866                    for (int i = 0; i < num; i++) {
4867                        synchronized (observer) {
4868                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4869                            observer.wait(200);  // Wait for write-close, give up after 200msec
4870                        }
4871                    }
4872                } catch (InterruptedException e) {
4873                    Log.wtf(TAG, e);
4874                }
4875            }
4876
4877            // Next collect the stacks of the native pids
4878            if (nativeProcs != null) {
4879                int[] pids = Process.getPidsForCommands(nativeProcs);
4880                if (pids != null) {
4881                    for (int pid : pids) {
4882                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4883                    }
4884                }
4885            }
4886
4887            // Lastly, measure CPU usage.
4888            if (processCpuTracker != null) {
4889                processCpuTracker.init();
4890                System.gc();
4891                processCpuTracker.update();
4892                try {
4893                    synchronized (processCpuTracker) {
4894                        processCpuTracker.wait(500); // measure over 1/2 second.
4895                    }
4896                } catch (InterruptedException e) {
4897                }
4898                processCpuTracker.update();
4899
4900                // We'll take the stack crawls of just the top apps using CPU.
4901                final int N = processCpuTracker.countWorkingStats();
4902                int numProcs = 0;
4903                for (int i=0; i<N && numProcs<5; i++) {
4904                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4905                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4906                        numProcs++;
4907                        try {
4908                            synchronized (observer) {
4909                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4910                                observer.wait(200);  // Wait for write-close, give up after 200msec
4911                            }
4912                        } catch (InterruptedException e) {
4913                            Log.wtf(TAG, e);
4914                        }
4915
4916                    }
4917                }
4918            }
4919        } finally {
4920            observer.stopWatching();
4921        }
4922    }
4923
4924    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4925        if (true || IS_USER_BUILD) {
4926            return;
4927        }
4928        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4929        if (tracesPath == null || tracesPath.length() == 0) {
4930            return;
4931        }
4932
4933        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4934        StrictMode.allowThreadDiskWrites();
4935        try {
4936            final File tracesFile = new File(tracesPath);
4937            final File tracesDir = tracesFile.getParentFile();
4938            final File tracesTmp = new File(tracesDir, "__tmp__");
4939            try {
4940                if (!tracesDir.exists()) {
4941                    tracesFile.mkdirs();
4942                    if (!SELinux.restorecon(tracesDir.getPath())) {
4943                        return;
4944                    }
4945                }
4946                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4947
4948                if (tracesFile.exists()) {
4949                    tracesTmp.delete();
4950                    tracesFile.renameTo(tracesTmp);
4951                }
4952                StringBuilder sb = new StringBuilder();
4953                Time tobj = new Time();
4954                tobj.set(System.currentTimeMillis());
4955                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4956                sb.append(": ");
4957                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4958                sb.append(" since ");
4959                sb.append(msg);
4960                FileOutputStream fos = new FileOutputStream(tracesFile);
4961                fos.write(sb.toString().getBytes());
4962                if (app == null) {
4963                    fos.write("\n*** No application process!".getBytes());
4964                }
4965                fos.close();
4966                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4967            } catch (IOException e) {
4968                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4969                return;
4970            }
4971
4972            if (app != null) {
4973                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4974                firstPids.add(app.pid);
4975                dumpStackTraces(tracesPath, firstPids, null, null, null);
4976            }
4977
4978            File lastTracesFile = null;
4979            File curTracesFile = null;
4980            for (int i=9; i>=0; i--) {
4981                String name = String.format(Locale.US, "slow%02d.txt", i);
4982                curTracesFile = new File(tracesDir, name);
4983                if (curTracesFile.exists()) {
4984                    if (lastTracesFile != null) {
4985                        curTracesFile.renameTo(lastTracesFile);
4986                    } else {
4987                        curTracesFile.delete();
4988                    }
4989                }
4990                lastTracesFile = curTracesFile;
4991            }
4992            tracesFile.renameTo(curTracesFile);
4993            if (tracesTmp.exists()) {
4994                tracesTmp.renameTo(tracesFile);
4995            }
4996        } finally {
4997            StrictMode.setThreadPolicy(oldPolicy);
4998        }
4999    }
5000
5001    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5002            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5003        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5004        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5005
5006        if (mController != null) {
5007            try {
5008                // 0 == continue, -1 = kill process immediately
5009                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5010                if (res < 0 && app.pid != MY_PID) {
5011                    app.kill("anr", true);
5012                }
5013            } catch (RemoteException e) {
5014                mController = null;
5015                Watchdog.getInstance().setActivityController(null);
5016            }
5017        }
5018
5019        long anrTime = SystemClock.uptimeMillis();
5020        if (MONITOR_CPU_USAGE) {
5021            updateCpuStatsNow();
5022        }
5023
5024        synchronized (this) {
5025            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5026            if (mShuttingDown) {
5027                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5028                return;
5029            } else if (app.notResponding) {
5030                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5031                return;
5032            } else if (app.crashing) {
5033                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5034                return;
5035            }
5036
5037            // In case we come through here for the same app before completing
5038            // this one, mark as anring now so we will bail out.
5039            app.notResponding = true;
5040
5041            // Log the ANR to the event log.
5042            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5043                    app.processName, app.info.flags, annotation);
5044
5045            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5046            firstPids.add(app.pid);
5047
5048            int parentPid = app.pid;
5049            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5050            if (parentPid != app.pid) firstPids.add(parentPid);
5051
5052            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5053
5054            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5055                ProcessRecord r = mLruProcesses.get(i);
5056                if (r != null && r.thread != null) {
5057                    int pid = r.pid;
5058                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5059                        if (r.persistent) {
5060                            firstPids.add(pid);
5061                        } else {
5062                            lastPids.put(pid, Boolean.TRUE);
5063                        }
5064                    }
5065                }
5066            }
5067        }
5068
5069        // Log the ANR to the main log.
5070        StringBuilder info = new StringBuilder();
5071        info.setLength(0);
5072        info.append("ANR in ").append(app.processName);
5073        if (activity != null && activity.shortComponentName != null) {
5074            info.append(" (").append(activity.shortComponentName).append(")");
5075        }
5076        info.append("\n");
5077        info.append("PID: ").append(app.pid).append("\n");
5078        if (annotation != null) {
5079            info.append("Reason: ").append(annotation).append("\n");
5080        }
5081        if (parent != null && parent != activity) {
5082            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5083        }
5084
5085        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5086
5087        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5088                NATIVE_STACKS_OF_INTEREST);
5089
5090        String cpuInfo = null;
5091        if (MONITOR_CPU_USAGE) {
5092            updateCpuStatsNow();
5093            synchronized (mProcessCpuTracker) {
5094                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5095            }
5096            info.append(processCpuTracker.printCurrentLoad());
5097            info.append(cpuInfo);
5098        }
5099
5100        info.append(processCpuTracker.printCurrentState(anrTime));
5101
5102        Slog.e(TAG, info.toString());
5103        if (tracesFile == null) {
5104            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5105            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5106        }
5107
5108        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5109                cpuInfo, tracesFile, null);
5110
5111        if (mController != null) {
5112            try {
5113                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5114                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5115                if (res != 0) {
5116                    if (res < 0 && app.pid != MY_PID) {
5117                        app.kill("anr", true);
5118                    } else {
5119                        synchronized (this) {
5120                            mServices.scheduleServiceTimeoutLocked(app);
5121                        }
5122                    }
5123                    return;
5124                }
5125            } catch (RemoteException e) {
5126                mController = null;
5127                Watchdog.getInstance().setActivityController(null);
5128            }
5129        }
5130
5131        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5132        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5133                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5134
5135        synchronized (this) {
5136            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5137                app.kill("bg anr", true);
5138                return;
5139            }
5140
5141            // Set the app's notResponding state, and look up the errorReportReceiver
5142            makeAppNotRespondingLocked(app,
5143                    activity != null ? activity.shortComponentName : null,
5144                    annotation != null ? "ANR " + annotation : "ANR",
5145                    info.toString());
5146
5147            // Bring up the infamous App Not Responding dialog
5148            Message msg = Message.obtain();
5149            HashMap<String, Object> map = new HashMap<String, Object>();
5150            msg.what = SHOW_NOT_RESPONDING_MSG;
5151            msg.obj = map;
5152            msg.arg1 = aboveSystem ? 1 : 0;
5153            map.put("app", app);
5154            if (activity != null) {
5155                map.put("activity", activity);
5156            }
5157
5158            mHandler.sendMessage(msg);
5159        }
5160    }
5161
5162    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5163        if (!mLaunchWarningShown) {
5164            mLaunchWarningShown = true;
5165            mHandler.post(new Runnable() {
5166                @Override
5167                public void run() {
5168                    synchronized (ActivityManagerService.this) {
5169                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5170                        d.show();
5171                        mHandler.postDelayed(new Runnable() {
5172                            @Override
5173                            public void run() {
5174                                synchronized (ActivityManagerService.this) {
5175                                    d.dismiss();
5176                                    mLaunchWarningShown = false;
5177                                }
5178                            }
5179                        }, 4000);
5180                    }
5181                }
5182            });
5183        }
5184    }
5185
5186    @Override
5187    public boolean clearApplicationUserData(final String packageName,
5188            final IPackageDataObserver observer, int userId) {
5189        enforceNotIsolatedCaller("clearApplicationUserData");
5190        int uid = Binder.getCallingUid();
5191        int pid = Binder.getCallingPid();
5192        userId = handleIncomingUser(pid, uid,
5193                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5194        long callingId = Binder.clearCallingIdentity();
5195        try {
5196            IPackageManager pm = AppGlobals.getPackageManager();
5197            int pkgUid = -1;
5198            synchronized(this) {
5199                try {
5200                    pkgUid = pm.getPackageUid(packageName, userId);
5201                } catch (RemoteException e) {
5202                }
5203                if (pkgUid == -1) {
5204                    Slog.w(TAG, "Invalid packageName: " + packageName);
5205                    if (observer != null) {
5206                        try {
5207                            observer.onRemoveCompleted(packageName, false);
5208                        } catch (RemoteException e) {
5209                            Slog.i(TAG, "Observer no longer exists.");
5210                        }
5211                    }
5212                    return false;
5213                }
5214                if (uid == pkgUid || checkComponentPermission(
5215                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5216                        pid, uid, -1, true)
5217                        == PackageManager.PERMISSION_GRANTED) {
5218                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5219                } else {
5220                    throw new SecurityException("PID " + pid + " does not have permission "
5221                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5222                                    + " of package " + packageName);
5223                }
5224
5225                // Remove all tasks match the cleared application package and user
5226                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5227                    final TaskRecord tr = mRecentTasks.get(i);
5228                    final String taskPackageName =
5229                            tr.getBaseIntent().getComponent().getPackageName();
5230                    if (tr.userId != userId) continue;
5231                    if (!taskPackageName.equals(packageName)) continue;
5232                    removeTaskByIdLocked(tr.taskId, 0);
5233                }
5234            }
5235
5236            try {
5237                // Clear application user data
5238                pm.clearApplicationUserData(packageName, observer, userId);
5239
5240                synchronized(this) {
5241                    // Remove all permissions granted from/to this package
5242                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5243                }
5244
5245                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5246                        Uri.fromParts("package", packageName, null));
5247                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5248                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5249                        null, null, 0, null, null, null, false, false, userId);
5250            } catch (RemoteException e) {
5251            }
5252        } finally {
5253            Binder.restoreCallingIdentity(callingId);
5254        }
5255        return true;
5256    }
5257
5258    @Override
5259    public void killBackgroundProcesses(final String packageName, int userId) {
5260        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5261                != PackageManager.PERMISSION_GRANTED &&
5262                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5263                        != PackageManager.PERMISSION_GRANTED) {
5264            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5265                    + Binder.getCallingPid()
5266                    + ", uid=" + Binder.getCallingUid()
5267                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5268            Slog.w(TAG, msg);
5269            throw new SecurityException(msg);
5270        }
5271
5272        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5273                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5274        long callingId = Binder.clearCallingIdentity();
5275        try {
5276            IPackageManager pm = AppGlobals.getPackageManager();
5277            synchronized(this) {
5278                int appId = -1;
5279                try {
5280                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5281                } catch (RemoteException e) {
5282                }
5283                if (appId == -1) {
5284                    Slog.w(TAG, "Invalid packageName: " + packageName);
5285                    return;
5286                }
5287                killPackageProcessesLocked(packageName, appId, userId,
5288                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5289            }
5290        } finally {
5291            Binder.restoreCallingIdentity(callingId);
5292        }
5293    }
5294
5295    @Override
5296    public void killAllBackgroundProcesses() {
5297        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5298                != PackageManager.PERMISSION_GRANTED) {
5299            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5300                    + Binder.getCallingPid()
5301                    + ", uid=" + Binder.getCallingUid()
5302                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5303            Slog.w(TAG, msg);
5304            throw new SecurityException(msg);
5305        }
5306
5307        long callingId = Binder.clearCallingIdentity();
5308        try {
5309            synchronized(this) {
5310                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5311                final int NP = mProcessNames.getMap().size();
5312                for (int ip=0; ip<NP; ip++) {
5313                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5314                    final int NA = apps.size();
5315                    for (int ia=0; ia<NA; ia++) {
5316                        ProcessRecord app = apps.valueAt(ia);
5317                        if (app.persistent) {
5318                            // we don't kill persistent processes
5319                            continue;
5320                        }
5321                        if (app.removed) {
5322                            procs.add(app);
5323                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5324                            app.removed = true;
5325                            procs.add(app);
5326                        }
5327                    }
5328                }
5329
5330                int N = procs.size();
5331                for (int i=0; i<N; i++) {
5332                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5333                }
5334                mAllowLowerMemLevel = true;
5335                updateOomAdjLocked();
5336                doLowMemReportIfNeededLocked(null);
5337            }
5338        } finally {
5339            Binder.restoreCallingIdentity(callingId);
5340        }
5341    }
5342
5343    @Override
5344    public void forceStopPackage(final String packageName, int userId) {
5345        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5346                != PackageManager.PERMISSION_GRANTED) {
5347            String msg = "Permission Denial: forceStopPackage() from pid="
5348                    + Binder.getCallingPid()
5349                    + ", uid=" + Binder.getCallingUid()
5350                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5351            Slog.w(TAG, msg);
5352            throw new SecurityException(msg);
5353        }
5354        final int callingPid = Binder.getCallingPid();
5355        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5356                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5357        long callingId = Binder.clearCallingIdentity();
5358        try {
5359            IPackageManager pm = AppGlobals.getPackageManager();
5360            synchronized(this) {
5361                int[] users = userId == UserHandle.USER_ALL
5362                        ? getUsersLocked() : new int[] { userId };
5363                for (int user : users) {
5364                    int pkgUid = -1;
5365                    try {
5366                        pkgUid = pm.getPackageUid(packageName, user);
5367                    } catch (RemoteException e) {
5368                    }
5369                    if (pkgUid == -1) {
5370                        Slog.w(TAG, "Invalid packageName: " + packageName);
5371                        continue;
5372                    }
5373                    try {
5374                        pm.setPackageStoppedState(packageName, true, user);
5375                    } catch (RemoteException e) {
5376                    } catch (IllegalArgumentException e) {
5377                        Slog.w(TAG, "Failed trying to unstop package "
5378                                + packageName + ": " + e);
5379                    }
5380                    if (isUserRunningLocked(user, false)) {
5381                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5382                    }
5383                }
5384            }
5385        } finally {
5386            Binder.restoreCallingIdentity(callingId);
5387        }
5388    }
5389
5390    @Override
5391    public void addPackageDependency(String packageName) {
5392        synchronized (this) {
5393            int callingPid = Binder.getCallingPid();
5394            if (callingPid == Process.myPid()) {
5395                //  Yeah, um, no.
5396                Slog.w(TAG, "Can't addPackageDependency on system process");
5397                return;
5398            }
5399            ProcessRecord proc;
5400            synchronized (mPidsSelfLocked) {
5401                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5402            }
5403            if (proc != null) {
5404                if (proc.pkgDeps == null) {
5405                    proc.pkgDeps = new ArraySet<String>(1);
5406                }
5407                proc.pkgDeps.add(packageName);
5408            }
5409        }
5410    }
5411
5412    /*
5413     * The pkg name and app id have to be specified.
5414     */
5415    @Override
5416    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5417        if (pkg == null) {
5418            return;
5419        }
5420        // Make sure the uid is valid.
5421        if (appid < 0) {
5422            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5423            return;
5424        }
5425        int callerUid = Binder.getCallingUid();
5426        // Only the system server can kill an application
5427        if (callerUid == Process.SYSTEM_UID) {
5428            // Post an aysnc message to kill the application
5429            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5430            msg.arg1 = appid;
5431            msg.arg2 = 0;
5432            Bundle bundle = new Bundle();
5433            bundle.putString("pkg", pkg);
5434            bundle.putString("reason", reason);
5435            msg.obj = bundle;
5436            mHandler.sendMessage(msg);
5437        } else {
5438            throw new SecurityException(callerUid + " cannot kill pkg: " +
5439                    pkg);
5440        }
5441    }
5442
5443    @Override
5444    public void closeSystemDialogs(String reason) {
5445        enforceNotIsolatedCaller("closeSystemDialogs");
5446
5447        final int pid = Binder.getCallingPid();
5448        final int uid = Binder.getCallingUid();
5449        final long origId = Binder.clearCallingIdentity();
5450        try {
5451            synchronized (this) {
5452                // Only allow this from foreground processes, so that background
5453                // applications can't abuse it to prevent system UI from being shown.
5454                if (uid >= Process.FIRST_APPLICATION_UID) {
5455                    ProcessRecord proc;
5456                    synchronized (mPidsSelfLocked) {
5457                        proc = mPidsSelfLocked.get(pid);
5458                    }
5459                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5460                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5461                                + " from background process " + proc);
5462                        return;
5463                    }
5464                }
5465                closeSystemDialogsLocked(reason);
5466            }
5467        } finally {
5468            Binder.restoreCallingIdentity(origId);
5469        }
5470    }
5471
5472    void closeSystemDialogsLocked(String reason) {
5473        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5474        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5475                | Intent.FLAG_RECEIVER_FOREGROUND);
5476        if (reason != null) {
5477            intent.putExtra("reason", reason);
5478        }
5479        mWindowManager.closeSystemDialogs(reason);
5480
5481        mStackSupervisor.closeSystemDialogsLocked();
5482
5483        broadcastIntentLocked(null, null, intent, null,
5484                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5485                Process.SYSTEM_UID, UserHandle.USER_ALL);
5486    }
5487
5488    @Override
5489    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5490        enforceNotIsolatedCaller("getProcessMemoryInfo");
5491        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5492        for (int i=pids.length-1; i>=0; i--) {
5493            ProcessRecord proc;
5494            int oomAdj;
5495            synchronized (this) {
5496                synchronized (mPidsSelfLocked) {
5497                    proc = mPidsSelfLocked.get(pids[i]);
5498                    oomAdj = proc != null ? proc.setAdj : 0;
5499                }
5500            }
5501            infos[i] = new Debug.MemoryInfo();
5502            Debug.getMemoryInfo(pids[i], infos[i]);
5503            if (proc != null) {
5504                synchronized (this) {
5505                    if (proc.thread != null && proc.setAdj == oomAdj) {
5506                        // Record this for posterity if the process has been stable.
5507                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5508                                infos[i].getTotalUss(), false, proc.pkgList);
5509                    }
5510                }
5511            }
5512        }
5513        return infos;
5514    }
5515
5516    @Override
5517    public long[] getProcessPss(int[] pids) {
5518        enforceNotIsolatedCaller("getProcessPss");
5519        long[] pss = new long[pids.length];
5520        for (int i=pids.length-1; i>=0; i--) {
5521            ProcessRecord proc;
5522            int oomAdj;
5523            synchronized (this) {
5524                synchronized (mPidsSelfLocked) {
5525                    proc = mPidsSelfLocked.get(pids[i]);
5526                    oomAdj = proc != null ? proc.setAdj : 0;
5527                }
5528            }
5529            long[] tmpUss = new long[1];
5530            pss[i] = Debug.getPss(pids[i], tmpUss);
5531            if (proc != null) {
5532                synchronized (this) {
5533                    if (proc.thread != null && proc.setAdj == oomAdj) {
5534                        // Record this for posterity if the process has been stable.
5535                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5536                    }
5537                }
5538            }
5539        }
5540        return pss;
5541    }
5542
5543    @Override
5544    public void killApplicationProcess(String processName, int uid) {
5545        if (processName == null) {
5546            return;
5547        }
5548
5549        int callerUid = Binder.getCallingUid();
5550        // Only the system server can kill an application
5551        if (callerUid == Process.SYSTEM_UID) {
5552            synchronized (this) {
5553                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5554                if (app != null && app.thread != null) {
5555                    try {
5556                        app.thread.scheduleSuicide();
5557                    } catch (RemoteException e) {
5558                        // If the other end already died, then our work here is done.
5559                    }
5560                } else {
5561                    Slog.w(TAG, "Process/uid not found attempting kill of "
5562                            + processName + " / " + uid);
5563                }
5564            }
5565        } else {
5566            throw new SecurityException(callerUid + " cannot kill app process: " +
5567                    processName);
5568        }
5569    }
5570
5571    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5572        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5573                false, true, false, false, UserHandle.getUserId(uid), reason);
5574        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5575                Uri.fromParts("package", packageName, null));
5576        if (!mProcessesReady) {
5577            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5578                    | Intent.FLAG_RECEIVER_FOREGROUND);
5579        }
5580        intent.putExtra(Intent.EXTRA_UID, uid);
5581        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5582        broadcastIntentLocked(null, null, intent,
5583                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5584                false, false,
5585                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5586    }
5587
5588    private void forceStopUserLocked(int userId, String reason) {
5589        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5590        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5591        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5592                | Intent.FLAG_RECEIVER_FOREGROUND);
5593        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5594        broadcastIntentLocked(null, null, intent,
5595                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5596                false, false,
5597                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5598    }
5599
5600    private final boolean killPackageProcessesLocked(String packageName, int appId,
5601            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5602            boolean doit, boolean evenPersistent, String reason) {
5603        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5604
5605        // Remove all processes this package may have touched: all with the
5606        // same UID (except for the system or root user), and all whose name
5607        // matches the package name.
5608        final int NP = mProcessNames.getMap().size();
5609        for (int ip=0; ip<NP; ip++) {
5610            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5611            final int NA = apps.size();
5612            for (int ia=0; ia<NA; ia++) {
5613                ProcessRecord app = apps.valueAt(ia);
5614                if (app.persistent && !evenPersistent) {
5615                    // we don't kill persistent processes
5616                    continue;
5617                }
5618                if (app.removed) {
5619                    if (doit) {
5620                        procs.add(app);
5621                    }
5622                    continue;
5623                }
5624
5625                // Skip process if it doesn't meet our oom adj requirement.
5626                if (app.setAdj < minOomAdj) {
5627                    continue;
5628                }
5629
5630                // If no package is specified, we call all processes under the
5631                // give user id.
5632                if (packageName == null) {
5633                    if (app.userId != userId) {
5634                        continue;
5635                    }
5636                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5637                        continue;
5638                    }
5639                // Package has been specified, we want to hit all processes
5640                // that match it.  We need to qualify this by the processes
5641                // that are running under the specified app and user ID.
5642                } else {
5643                    final boolean isDep = app.pkgDeps != null
5644                            && app.pkgDeps.contains(packageName);
5645                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5646                        continue;
5647                    }
5648                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5649                        continue;
5650                    }
5651                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5652                        continue;
5653                    }
5654                }
5655
5656                // Process has passed all conditions, kill it!
5657                if (!doit) {
5658                    return true;
5659                }
5660                app.removed = true;
5661                procs.add(app);
5662            }
5663        }
5664
5665        int N = procs.size();
5666        for (int i=0; i<N; i++) {
5667            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5668        }
5669        updateOomAdjLocked();
5670        return N > 0;
5671    }
5672
5673    private final boolean forceStopPackageLocked(String name, int appId,
5674            boolean callerWillRestart, boolean purgeCache, boolean doit,
5675            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5676        int i;
5677        int N;
5678
5679        if (userId == UserHandle.USER_ALL && name == null) {
5680            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5681        }
5682
5683        if (appId < 0 && name != null) {
5684            try {
5685                appId = UserHandle.getAppId(
5686                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5687            } catch (RemoteException e) {
5688            }
5689        }
5690
5691        if (doit) {
5692            if (name != null) {
5693                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5694                        + " user=" + userId + ": " + reason);
5695            } else {
5696                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5697            }
5698
5699            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5700            for (int ip=pmap.size()-1; ip>=0; ip--) {
5701                SparseArray<Long> ba = pmap.valueAt(ip);
5702                for (i=ba.size()-1; i>=0; i--) {
5703                    boolean remove = false;
5704                    final int entUid = ba.keyAt(i);
5705                    if (name != null) {
5706                        if (userId == UserHandle.USER_ALL) {
5707                            if (UserHandle.getAppId(entUid) == appId) {
5708                                remove = true;
5709                            }
5710                        } else {
5711                            if (entUid == UserHandle.getUid(userId, appId)) {
5712                                remove = true;
5713                            }
5714                        }
5715                    } else if (UserHandle.getUserId(entUid) == userId) {
5716                        remove = true;
5717                    }
5718                    if (remove) {
5719                        ba.removeAt(i);
5720                    }
5721                }
5722                if (ba.size() == 0) {
5723                    pmap.removeAt(ip);
5724                }
5725            }
5726        }
5727
5728        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5729                -100, callerWillRestart, true, doit, evenPersistent,
5730                name == null ? ("stop user " + userId) : ("stop " + name));
5731
5732        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5733            if (!doit) {
5734                return true;
5735            }
5736            didSomething = true;
5737        }
5738
5739        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5740            if (!doit) {
5741                return true;
5742            }
5743            didSomething = true;
5744        }
5745
5746        if (name == null) {
5747            // Remove all sticky broadcasts from this user.
5748            mStickyBroadcasts.remove(userId);
5749        }
5750
5751        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5752        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5753                userId, providers)) {
5754            if (!doit) {
5755                return true;
5756            }
5757            didSomething = true;
5758        }
5759        N = providers.size();
5760        for (i=0; i<N; i++) {
5761            removeDyingProviderLocked(null, providers.get(i), true);
5762        }
5763
5764        // Remove transient permissions granted from/to this package/user
5765        removeUriPermissionsForPackageLocked(name, userId, false);
5766
5767        if (name == null || uninstalling) {
5768            // Remove pending intents.  For now we only do this when force
5769            // stopping users, because we have some problems when doing this
5770            // for packages -- app widgets are not currently cleaned up for
5771            // such packages, so they can be left with bad pending intents.
5772            if (mIntentSenderRecords.size() > 0) {
5773                Iterator<WeakReference<PendingIntentRecord>> it
5774                        = mIntentSenderRecords.values().iterator();
5775                while (it.hasNext()) {
5776                    WeakReference<PendingIntentRecord> wpir = it.next();
5777                    if (wpir == null) {
5778                        it.remove();
5779                        continue;
5780                    }
5781                    PendingIntentRecord pir = wpir.get();
5782                    if (pir == null) {
5783                        it.remove();
5784                        continue;
5785                    }
5786                    if (name == null) {
5787                        // Stopping user, remove all objects for the user.
5788                        if (pir.key.userId != userId) {
5789                            // Not the same user, skip it.
5790                            continue;
5791                        }
5792                    } else {
5793                        if (UserHandle.getAppId(pir.uid) != appId) {
5794                            // Different app id, skip it.
5795                            continue;
5796                        }
5797                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5798                            // Different user, skip it.
5799                            continue;
5800                        }
5801                        if (!pir.key.packageName.equals(name)) {
5802                            // Different package, skip it.
5803                            continue;
5804                        }
5805                    }
5806                    if (!doit) {
5807                        return true;
5808                    }
5809                    didSomething = true;
5810                    it.remove();
5811                    pir.canceled = true;
5812                    if (pir.key.activity != null) {
5813                        pir.key.activity.pendingResults.remove(pir.ref);
5814                    }
5815                }
5816            }
5817        }
5818
5819        if (doit) {
5820            if (purgeCache && name != null) {
5821                AttributeCache ac = AttributeCache.instance();
5822                if (ac != null) {
5823                    ac.removePackage(name);
5824                }
5825            }
5826            if (mBooted) {
5827                mStackSupervisor.resumeTopActivitiesLocked();
5828                mStackSupervisor.scheduleIdleLocked();
5829            }
5830        }
5831
5832        return didSomething;
5833    }
5834
5835    private final boolean removeProcessLocked(ProcessRecord app,
5836            boolean callerWillRestart, boolean allowRestart, String reason) {
5837        final String name = app.processName;
5838        final int uid = app.uid;
5839        if (DEBUG_PROCESSES) Slog.d(
5840            TAG, "Force removing proc " + app.toShortString() + " (" + name
5841            + "/" + uid + ")");
5842
5843        mProcessNames.remove(name, uid);
5844        mIsolatedProcesses.remove(app.uid);
5845        if (mHeavyWeightProcess == app) {
5846            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5847                    mHeavyWeightProcess.userId, 0));
5848            mHeavyWeightProcess = null;
5849        }
5850        boolean needRestart = false;
5851        if (app.pid > 0 && app.pid != MY_PID) {
5852            int pid = app.pid;
5853            synchronized (mPidsSelfLocked) {
5854                mPidsSelfLocked.remove(pid);
5855                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5856            }
5857            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5858            if (app.isolated) {
5859                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5860            }
5861            app.kill(reason, true);
5862            handleAppDiedLocked(app, true, allowRestart);
5863            removeLruProcessLocked(app);
5864
5865            if (app.persistent && !app.isolated) {
5866                if (!callerWillRestart) {
5867                    addAppLocked(app.info, false, null /* ABI override */);
5868                } else {
5869                    needRestart = true;
5870                }
5871            }
5872        } else {
5873            mRemovedProcesses.add(app);
5874        }
5875
5876        return needRestart;
5877    }
5878
5879    private final void processStartTimedOutLocked(ProcessRecord app) {
5880        final int pid = app.pid;
5881        boolean gone = false;
5882        synchronized (mPidsSelfLocked) {
5883            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5884            if (knownApp != null && knownApp.thread == null) {
5885                mPidsSelfLocked.remove(pid);
5886                gone = true;
5887            }
5888        }
5889
5890        if (gone) {
5891            Slog.w(TAG, "Process " + app + " failed to attach");
5892            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5893                    pid, app.uid, app.processName);
5894            mProcessNames.remove(app.processName, app.uid);
5895            mIsolatedProcesses.remove(app.uid);
5896            if (mHeavyWeightProcess == app) {
5897                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5898                        mHeavyWeightProcess.userId, 0));
5899                mHeavyWeightProcess = null;
5900            }
5901            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5902            if (app.isolated) {
5903                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5904            }
5905            // Take care of any launching providers waiting for this process.
5906            checkAppInLaunchingProvidersLocked(app, true);
5907            // Take care of any services that are waiting for the process.
5908            mServices.processStartTimedOutLocked(app);
5909            app.kill("start timeout", true);
5910            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5911                Slog.w(TAG, "Unattached app died before backup, skipping");
5912                try {
5913                    IBackupManager bm = IBackupManager.Stub.asInterface(
5914                            ServiceManager.getService(Context.BACKUP_SERVICE));
5915                    bm.agentDisconnected(app.info.packageName);
5916                } catch (RemoteException e) {
5917                    // Can't happen; the backup manager is local
5918                }
5919            }
5920            if (isPendingBroadcastProcessLocked(pid)) {
5921                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5922                skipPendingBroadcastLocked(pid);
5923            }
5924        } else {
5925            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5926        }
5927    }
5928
5929    private final boolean attachApplicationLocked(IApplicationThread thread,
5930            int pid) {
5931
5932        // Find the application record that is being attached...  either via
5933        // the pid if we are running in multiple processes, or just pull the
5934        // next app record if we are emulating process with anonymous threads.
5935        ProcessRecord app;
5936        if (pid != MY_PID && pid >= 0) {
5937            synchronized (mPidsSelfLocked) {
5938                app = mPidsSelfLocked.get(pid);
5939            }
5940        } else {
5941            app = null;
5942        }
5943
5944        if (app == null) {
5945            Slog.w(TAG, "No pending application record for pid " + pid
5946                    + " (IApplicationThread " + thread + "); dropping process");
5947            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5948            if (pid > 0 && pid != MY_PID) {
5949                Process.killProcessQuiet(pid);
5950                //TODO: Process.killProcessGroup(app.info.uid, pid);
5951            } else {
5952                try {
5953                    thread.scheduleExit();
5954                } catch (Exception e) {
5955                    // Ignore exceptions.
5956                }
5957            }
5958            return false;
5959        }
5960
5961        // If this application record is still attached to a previous
5962        // process, clean it up now.
5963        if (app.thread != null) {
5964            handleAppDiedLocked(app, true, true);
5965        }
5966
5967        // Tell the process all about itself.
5968
5969        if (localLOGV) Slog.v(
5970                TAG, "Binding process pid " + pid + " to record " + app);
5971
5972        final String processName = app.processName;
5973        try {
5974            AppDeathRecipient adr = new AppDeathRecipient(
5975                    app, pid, thread);
5976            thread.asBinder().linkToDeath(adr, 0);
5977            app.deathRecipient = adr;
5978        } catch (RemoteException e) {
5979            app.resetPackageList(mProcessStats);
5980            startProcessLocked(app, "link fail", processName);
5981            return false;
5982        }
5983
5984        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5985
5986        app.makeActive(thread, mProcessStats);
5987        app.curAdj = app.setAdj = -100;
5988        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5989        app.forcingToForeground = null;
5990        updateProcessForegroundLocked(app, false, false);
5991        app.hasShownUi = false;
5992        app.debugging = false;
5993        app.cached = false;
5994
5995        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5996
5997        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5998        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5999
6000        if (!normalMode) {
6001            Slog.i(TAG, "Launching preboot mode app: " + app);
6002        }
6003
6004        if (localLOGV) Slog.v(
6005            TAG, "New app record " + app
6006            + " thread=" + thread.asBinder() + " pid=" + pid);
6007        try {
6008            int testMode = IApplicationThread.DEBUG_OFF;
6009            if (mDebugApp != null && mDebugApp.equals(processName)) {
6010                testMode = mWaitForDebugger
6011                    ? IApplicationThread.DEBUG_WAIT
6012                    : IApplicationThread.DEBUG_ON;
6013                app.debugging = true;
6014                if (mDebugTransient) {
6015                    mDebugApp = mOrigDebugApp;
6016                    mWaitForDebugger = mOrigWaitForDebugger;
6017                }
6018            }
6019            String profileFile = app.instrumentationProfileFile;
6020            ParcelFileDescriptor profileFd = null;
6021            int samplingInterval = 0;
6022            boolean profileAutoStop = false;
6023            if (mProfileApp != null && mProfileApp.equals(processName)) {
6024                mProfileProc = app;
6025                profileFile = mProfileFile;
6026                profileFd = mProfileFd;
6027                samplingInterval = mSamplingInterval;
6028                profileAutoStop = mAutoStopProfiler;
6029            }
6030            boolean enableOpenGlTrace = false;
6031            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6032                enableOpenGlTrace = true;
6033                mOpenGlTraceApp = null;
6034            }
6035
6036            // If the app is being launched for restore or full backup, set it up specially
6037            boolean isRestrictedBackupMode = false;
6038            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6039                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6040                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6041                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6042            }
6043
6044            ensurePackageDexOpt(app.instrumentationInfo != null
6045                    ? app.instrumentationInfo.packageName
6046                    : app.info.packageName);
6047            if (app.instrumentationClass != null) {
6048                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6049            }
6050            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6051                    + processName + " with config " + mConfiguration);
6052            ApplicationInfo appInfo = app.instrumentationInfo != null
6053                    ? app.instrumentationInfo : app.info;
6054            app.compat = compatibilityInfoForPackageLocked(appInfo);
6055            if (profileFd != null) {
6056                profileFd = profileFd.dup();
6057            }
6058            ProfilerInfo profilerInfo = profileFile == null ? null
6059                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6060            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6061                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6062                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6063                    isRestrictedBackupMode || !normalMode, app.persistent,
6064                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6065                    mCoreSettingsObserver.getCoreSettingsLocked());
6066            updateLruProcessLocked(app, false, null);
6067            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6068        } catch (Exception e) {
6069            // todo: Yikes!  What should we do?  For now we will try to
6070            // start another process, but that could easily get us in
6071            // an infinite loop of restarting processes...
6072            Slog.w(TAG, "Exception thrown during bind!", e);
6073
6074            app.resetPackageList(mProcessStats);
6075            app.unlinkDeathRecipient();
6076            startProcessLocked(app, "bind fail", processName);
6077            return false;
6078        }
6079
6080        // Remove this record from the list of starting applications.
6081        mPersistentStartingProcesses.remove(app);
6082        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6083                "Attach application locked removing on hold: " + app);
6084        mProcessesOnHold.remove(app);
6085
6086        boolean badApp = false;
6087        boolean didSomething = false;
6088
6089        // See if the top visible activity is waiting to run in this process...
6090        if (normalMode) {
6091            try {
6092                if (mStackSupervisor.attachApplicationLocked(app)) {
6093                    didSomething = true;
6094                }
6095            } catch (Exception e) {
6096                badApp = true;
6097            }
6098        }
6099
6100        // Find any services that should be running in this process...
6101        if (!badApp) {
6102            try {
6103                didSomething |= mServices.attachApplicationLocked(app, processName);
6104            } catch (Exception e) {
6105                badApp = true;
6106            }
6107        }
6108
6109        // Check if a next-broadcast receiver is in this process...
6110        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6111            try {
6112                didSomething |= sendPendingBroadcastsLocked(app);
6113            } catch (Exception e) {
6114                // If the app died trying to launch the receiver we declare it 'bad'
6115                badApp = true;
6116            }
6117        }
6118
6119        // Check whether the next backup agent is in this process...
6120        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6121            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6122            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6123            try {
6124                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6125                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6126                        mBackupTarget.backupMode);
6127            } catch (Exception e) {
6128                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6129                e.printStackTrace();
6130            }
6131        }
6132
6133        if (badApp) {
6134            // todo: Also need to kill application to deal with all
6135            // kinds of exceptions.
6136            handleAppDiedLocked(app, false, true);
6137            return false;
6138        }
6139
6140        if (!didSomething) {
6141            updateOomAdjLocked();
6142        }
6143
6144        return true;
6145    }
6146
6147    @Override
6148    public final void attachApplication(IApplicationThread thread) {
6149        synchronized (this) {
6150            int callingPid = Binder.getCallingPid();
6151            final long origId = Binder.clearCallingIdentity();
6152            attachApplicationLocked(thread, callingPid);
6153            Binder.restoreCallingIdentity(origId);
6154        }
6155    }
6156
6157    @Override
6158    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6159        final long origId = Binder.clearCallingIdentity();
6160        synchronized (this) {
6161            ActivityStack stack = ActivityRecord.getStackLocked(token);
6162            if (stack != null) {
6163                ActivityRecord r =
6164                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6165                if (stopProfiling) {
6166                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6167                        try {
6168                            mProfileFd.close();
6169                        } catch (IOException e) {
6170                        }
6171                        clearProfilerLocked();
6172                    }
6173                }
6174            }
6175        }
6176        Binder.restoreCallingIdentity(origId);
6177    }
6178
6179    void postEnableScreenAfterBootLocked() {
6180        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6181    }
6182
6183    void enableScreenAfterBoot() {
6184        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6185                SystemClock.uptimeMillis());
6186        mWindowManager.enableScreenAfterBoot();
6187
6188        synchronized (this) {
6189            updateEventDispatchingLocked();
6190        }
6191    }
6192
6193    @Override
6194    public void showBootMessage(final CharSequence msg, final boolean always) {
6195        enforceNotIsolatedCaller("showBootMessage");
6196        mWindowManager.showBootMessage(msg, always);
6197    }
6198
6199    @Override
6200    public void keyguardWaitingForActivityDrawn() {
6201        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6202        final long token = Binder.clearCallingIdentity();
6203        try {
6204            synchronized (this) {
6205                if (DEBUG_LOCKSCREEN) logLockScreen("");
6206                mWindowManager.keyguardWaitingForActivityDrawn();
6207            }
6208        } finally {
6209            Binder.restoreCallingIdentity(token);
6210        }
6211    }
6212
6213    final void finishBooting() {
6214        synchronized (this) {
6215            if (!mBootAnimationComplete) {
6216                mCallFinishBooting = true;
6217                return;
6218            }
6219            mCallFinishBooting = false;
6220        }
6221
6222        // Register receivers to handle package update events
6223        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6224
6225        // Let system services know.
6226        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6227
6228        synchronized (this) {
6229            // Ensure that any processes we had put on hold are now started
6230            // up.
6231            final int NP = mProcessesOnHold.size();
6232            if (NP > 0) {
6233                ArrayList<ProcessRecord> procs =
6234                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6235                for (int ip=0; ip<NP; ip++) {
6236                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6237                            + procs.get(ip));
6238                    startProcessLocked(procs.get(ip), "on-hold", null);
6239                }
6240            }
6241
6242            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6243                // Start looking for apps that are abusing wake locks.
6244                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6245                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6246                // Tell anyone interested that we are done booting!
6247                SystemProperties.set("sys.boot_completed", "1");
6248                SystemProperties.set("dev.bootcomplete", "1");
6249                for (int i=0; i<mStartedUsers.size(); i++) {
6250                    UserStartedState uss = mStartedUsers.valueAt(i);
6251                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6252                        uss.mState = UserStartedState.STATE_RUNNING;
6253                        final int userId = mStartedUsers.keyAt(i);
6254                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6255                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6256                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6257                        broadcastIntentLocked(null, null, intent, null,
6258                                new IIntentReceiver.Stub() {
6259                                    @Override
6260                                    public void performReceive(Intent intent, int resultCode,
6261                                            String data, Bundle extras, boolean ordered,
6262                                            boolean sticky, int sendingUser) {
6263                                        synchronized (ActivityManagerService.this) {
6264                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6265                                                    true, false);
6266                                        }
6267                                    }
6268                                },
6269                                0, null, null,
6270                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6271                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6272                                userId);
6273                    }
6274                }
6275                scheduleStartProfilesLocked();
6276            }
6277        }
6278    }
6279
6280    @Override
6281    public void bootAnimationComplete() {
6282        final boolean callFinishBooting;
6283        synchronized (this) {
6284            callFinishBooting = mCallFinishBooting;
6285            mBootAnimationComplete = true;
6286        }
6287        if (callFinishBooting) {
6288            finishBooting();
6289        }
6290    }
6291
6292    final void ensureBootCompleted() {
6293        boolean booting;
6294        boolean enableScreen;
6295        synchronized (this) {
6296            booting = mBooting;
6297            mBooting = false;
6298            enableScreen = !mBooted;
6299            mBooted = true;
6300        }
6301
6302        if (booting) {
6303            finishBooting();
6304        }
6305
6306        if (enableScreen) {
6307            enableScreenAfterBoot();
6308        }
6309    }
6310
6311    @Override
6312    public final void activityResumed(IBinder token) {
6313        final long origId = Binder.clearCallingIdentity();
6314        synchronized(this) {
6315            ActivityStack stack = ActivityRecord.getStackLocked(token);
6316            if (stack != null) {
6317                ActivityRecord.activityResumedLocked(token);
6318            }
6319        }
6320        Binder.restoreCallingIdentity(origId);
6321    }
6322
6323    @Override
6324    public final void activityPaused(IBinder token) {
6325        final long origId = Binder.clearCallingIdentity();
6326        synchronized(this) {
6327            ActivityStack stack = ActivityRecord.getStackLocked(token);
6328            if (stack != null) {
6329                stack.activityPausedLocked(token, false);
6330            }
6331        }
6332        Binder.restoreCallingIdentity(origId);
6333    }
6334
6335    @Override
6336    public final void activityStopped(IBinder token, Bundle icicle,
6337            PersistableBundle persistentState, CharSequence description) {
6338        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6339
6340        // Refuse possible leaked file descriptors
6341        if (icicle != null && icicle.hasFileDescriptors()) {
6342            throw new IllegalArgumentException("File descriptors passed in Bundle");
6343        }
6344
6345        final long origId = Binder.clearCallingIdentity();
6346
6347        synchronized (this) {
6348            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6349            if (r != null) {
6350                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6351            }
6352        }
6353
6354        trimApplications();
6355
6356        Binder.restoreCallingIdentity(origId);
6357    }
6358
6359    @Override
6360    public final void activityDestroyed(IBinder token) {
6361        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6362        synchronized (this) {
6363            ActivityStack stack = ActivityRecord.getStackLocked(token);
6364            if (stack != null) {
6365                stack.activityDestroyedLocked(token);
6366            }
6367        }
6368    }
6369
6370    @Override
6371    public final void backgroundResourcesReleased(IBinder token) {
6372        final long origId = Binder.clearCallingIdentity();
6373        try {
6374            synchronized (this) {
6375                ActivityStack stack = ActivityRecord.getStackLocked(token);
6376                if (stack != null) {
6377                    stack.backgroundResourcesReleased(token);
6378                }
6379            }
6380        } finally {
6381            Binder.restoreCallingIdentity(origId);
6382        }
6383    }
6384
6385    @Override
6386    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6387        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6388    }
6389
6390    @Override
6391    public final void notifyEnterAnimationComplete(IBinder token) {
6392        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6393    }
6394
6395    @Override
6396    public String getCallingPackage(IBinder token) {
6397        synchronized (this) {
6398            ActivityRecord r = getCallingRecordLocked(token);
6399            return r != null ? r.info.packageName : null;
6400        }
6401    }
6402
6403    @Override
6404    public ComponentName getCallingActivity(IBinder token) {
6405        synchronized (this) {
6406            ActivityRecord r = getCallingRecordLocked(token);
6407            return r != null ? r.intent.getComponent() : null;
6408        }
6409    }
6410
6411    private ActivityRecord getCallingRecordLocked(IBinder token) {
6412        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6413        if (r == null) {
6414            return null;
6415        }
6416        return r.resultTo;
6417    }
6418
6419    @Override
6420    public ComponentName getActivityClassForToken(IBinder token) {
6421        synchronized(this) {
6422            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6423            if (r == null) {
6424                return null;
6425            }
6426            return r.intent.getComponent();
6427        }
6428    }
6429
6430    @Override
6431    public String getPackageForToken(IBinder token) {
6432        synchronized(this) {
6433            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6434            if (r == null) {
6435                return null;
6436            }
6437            return r.packageName;
6438        }
6439    }
6440
6441    @Override
6442    public IIntentSender getIntentSender(int type,
6443            String packageName, IBinder token, String resultWho,
6444            int requestCode, Intent[] intents, String[] resolvedTypes,
6445            int flags, Bundle options, int userId) {
6446        enforceNotIsolatedCaller("getIntentSender");
6447        // Refuse possible leaked file descriptors
6448        if (intents != null) {
6449            if (intents.length < 1) {
6450                throw new IllegalArgumentException("Intents array length must be >= 1");
6451            }
6452            for (int i=0; i<intents.length; i++) {
6453                Intent intent = intents[i];
6454                if (intent != null) {
6455                    if (intent.hasFileDescriptors()) {
6456                        throw new IllegalArgumentException("File descriptors passed in Intent");
6457                    }
6458                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6459                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6460                        throw new IllegalArgumentException(
6461                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6462                    }
6463                    intents[i] = new Intent(intent);
6464                }
6465            }
6466            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6467                throw new IllegalArgumentException(
6468                        "Intent array length does not match resolvedTypes length");
6469            }
6470        }
6471        if (options != null) {
6472            if (options.hasFileDescriptors()) {
6473                throw new IllegalArgumentException("File descriptors passed in options");
6474            }
6475        }
6476
6477        synchronized(this) {
6478            int callingUid = Binder.getCallingUid();
6479            int origUserId = userId;
6480            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6481                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6482                    ALLOW_NON_FULL, "getIntentSender", null);
6483            if (origUserId == UserHandle.USER_CURRENT) {
6484                // We don't want to evaluate this until the pending intent is
6485                // actually executed.  However, we do want to always do the
6486                // security checking for it above.
6487                userId = UserHandle.USER_CURRENT;
6488            }
6489            try {
6490                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6491                    int uid = AppGlobals.getPackageManager()
6492                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6493                    if (!UserHandle.isSameApp(callingUid, uid)) {
6494                        String msg = "Permission Denial: getIntentSender() from pid="
6495                            + Binder.getCallingPid()
6496                            + ", uid=" + Binder.getCallingUid()
6497                            + ", (need uid=" + uid + ")"
6498                            + " is not allowed to send as package " + packageName;
6499                        Slog.w(TAG, msg);
6500                        throw new SecurityException(msg);
6501                    }
6502                }
6503
6504                return getIntentSenderLocked(type, packageName, callingUid, userId,
6505                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6506
6507            } catch (RemoteException e) {
6508                throw new SecurityException(e);
6509            }
6510        }
6511    }
6512
6513    IIntentSender getIntentSenderLocked(int type, String packageName,
6514            int callingUid, int userId, IBinder token, String resultWho,
6515            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6516            Bundle options) {
6517        if (DEBUG_MU)
6518            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6519        ActivityRecord activity = null;
6520        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6521            activity = ActivityRecord.isInStackLocked(token);
6522            if (activity == null) {
6523                return null;
6524            }
6525            if (activity.finishing) {
6526                return null;
6527            }
6528        }
6529
6530        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6531        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6532        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6533        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6534                |PendingIntent.FLAG_UPDATE_CURRENT);
6535
6536        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6537                type, packageName, activity, resultWho,
6538                requestCode, intents, resolvedTypes, flags, options, userId);
6539        WeakReference<PendingIntentRecord> ref;
6540        ref = mIntentSenderRecords.get(key);
6541        PendingIntentRecord rec = ref != null ? ref.get() : null;
6542        if (rec != null) {
6543            if (!cancelCurrent) {
6544                if (updateCurrent) {
6545                    if (rec.key.requestIntent != null) {
6546                        rec.key.requestIntent.replaceExtras(intents != null ?
6547                                intents[intents.length - 1] : null);
6548                    }
6549                    if (intents != null) {
6550                        intents[intents.length-1] = rec.key.requestIntent;
6551                        rec.key.allIntents = intents;
6552                        rec.key.allResolvedTypes = resolvedTypes;
6553                    } else {
6554                        rec.key.allIntents = null;
6555                        rec.key.allResolvedTypes = null;
6556                    }
6557                }
6558                return rec;
6559            }
6560            rec.canceled = true;
6561            mIntentSenderRecords.remove(key);
6562        }
6563        if (noCreate) {
6564            return rec;
6565        }
6566        rec = new PendingIntentRecord(this, key, callingUid);
6567        mIntentSenderRecords.put(key, rec.ref);
6568        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6569            if (activity.pendingResults == null) {
6570                activity.pendingResults
6571                        = new HashSet<WeakReference<PendingIntentRecord>>();
6572            }
6573            activity.pendingResults.add(rec.ref);
6574        }
6575        return rec;
6576    }
6577
6578    @Override
6579    public void cancelIntentSender(IIntentSender sender) {
6580        if (!(sender instanceof PendingIntentRecord)) {
6581            return;
6582        }
6583        synchronized(this) {
6584            PendingIntentRecord rec = (PendingIntentRecord)sender;
6585            try {
6586                int uid = AppGlobals.getPackageManager()
6587                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6588                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6589                    String msg = "Permission Denial: cancelIntentSender() from pid="
6590                        + Binder.getCallingPid()
6591                        + ", uid=" + Binder.getCallingUid()
6592                        + " is not allowed to cancel packges "
6593                        + rec.key.packageName;
6594                    Slog.w(TAG, msg);
6595                    throw new SecurityException(msg);
6596                }
6597            } catch (RemoteException e) {
6598                throw new SecurityException(e);
6599            }
6600            cancelIntentSenderLocked(rec, true);
6601        }
6602    }
6603
6604    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6605        rec.canceled = true;
6606        mIntentSenderRecords.remove(rec.key);
6607        if (cleanActivity && rec.key.activity != null) {
6608            rec.key.activity.pendingResults.remove(rec.ref);
6609        }
6610    }
6611
6612    @Override
6613    public String getPackageForIntentSender(IIntentSender pendingResult) {
6614        if (!(pendingResult instanceof PendingIntentRecord)) {
6615            return null;
6616        }
6617        try {
6618            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6619            return res.key.packageName;
6620        } catch (ClassCastException e) {
6621        }
6622        return null;
6623    }
6624
6625    @Override
6626    public int getUidForIntentSender(IIntentSender sender) {
6627        if (sender instanceof PendingIntentRecord) {
6628            try {
6629                PendingIntentRecord res = (PendingIntentRecord)sender;
6630                return res.uid;
6631            } catch (ClassCastException e) {
6632            }
6633        }
6634        return -1;
6635    }
6636
6637    @Override
6638    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6639        if (!(pendingResult instanceof PendingIntentRecord)) {
6640            return false;
6641        }
6642        try {
6643            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6644            if (res.key.allIntents == null) {
6645                return false;
6646            }
6647            for (int i=0; i<res.key.allIntents.length; i++) {
6648                Intent intent = res.key.allIntents[i];
6649                if (intent.getPackage() != null && intent.getComponent() != null) {
6650                    return false;
6651                }
6652            }
6653            return true;
6654        } catch (ClassCastException e) {
6655        }
6656        return false;
6657    }
6658
6659    @Override
6660    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6661        if (!(pendingResult instanceof PendingIntentRecord)) {
6662            return false;
6663        }
6664        try {
6665            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6666            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6667                return true;
6668            }
6669            return false;
6670        } catch (ClassCastException e) {
6671        }
6672        return false;
6673    }
6674
6675    @Override
6676    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6677        if (!(pendingResult instanceof PendingIntentRecord)) {
6678            return null;
6679        }
6680        try {
6681            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6682            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6683        } catch (ClassCastException e) {
6684        }
6685        return null;
6686    }
6687
6688    @Override
6689    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6690        if (!(pendingResult instanceof PendingIntentRecord)) {
6691            return null;
6692        }
6693        try {
6694            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6695            Intent intent = res.key.requestIntent;
6696            if (intent != null) {
6697                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6698                        || res.lastTagPrefix.equals(prefix))) {
6699                    return res.lastTag;
6700                }
6701                res.lastTagPrefix = prefix;
6702                StringBuilder sb = new StringBuilder(128);
6703                if (prefix != null) {
6704                    sb.append(prefix);
6705                }
6706                if (intent.getAction() != null) {
6707                    sb.append(intent.getAction());
6708                } else if (intent.getComponent() != null) {
6709                    intent.getComponent().appendShortString(sb);
6710                } else {
6711                    sb.append("?");
6712                }
6713                return res.lastTag = sb.toString();
6714            }
6715        } catch (ClassCastException e) {
6716        }
6717        return null;
6718    }
6719
6720    @Override
6721    public void setProcessLimit(int max) {
6722        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6723                "setProcessLimit()");
6724        synchronized (this) {
6725            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6726            mProcessLimitOverride = max;
6727        }
6728        trimApplications();
6729    }
6730
6731    @Override
6732    public int getProcessLimit() {
6733        synchronized (this) {
6734            return mProcessLimitOverride;
6735        }
6736    }
6737
6738    void foregroundTokenDied(ForegroundToken token) {
6739        synchronized (ActivityManagerService.this) {
6740            synchronized (mPidsSelfLocked) {
6741                ForegroundToken cur
6742                    = mForegroundProcesses.get(token.pid);
6743                if (cur != token) {
6744                    return;
6745                }
6746                mForegroundProcesses.remove(token.pid);
6747                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6748                if (pr == null) {
6749                    return;
6750                }
6751                pr.forcingToForeground = null;
6752                updateProcessForegroundLocked(pr, false, false);
6753            }
6754            updateOomAdjLocked();
6755        }
6756    }
6757
6758    @Override
6759    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6760        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6761                "setProcessForeground()");
6762        synchronized(this) {
6763            boolean changed = false;
6764
6765            synchronized (mPidsSelfLocked) {
6766                ProcessRecord pr = mPidsSelfLocked.get(pid);
6767                if (pr == null && isForeground) {
6768                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6769                    return;
6770                }
6771                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6772                if (oldToken != null) {
6773                    oldToken.token.unlinkToDeath(oldToken, 0);
6774                    mForegroundProcesses.remove(pid);
6775                    if (pr != null) {
6776                        pr.forcingToForeground = null;
6777                    }
6778                    changed = true;
6779                }
6780                if (isForeground && token != null) {
6781                    ForegroundToken newToken = new ForegroundToken() {
6782                        @Override
6783                        public void binderDied() {
6784                            foregroundTokenDied(this);
6785                        }
6786                    };
6787                    newToken.pid = pid;
6788                    newToken.token = token;
6789                    try {
6790                        token.linkToDeath(newToken, 0);
6791                        mForegroundProcesses.put(pid, newToken);
6792                        pr.forcingToForeground = token;
6793                        changed = true;
6794                    } catch (RemoteException e) {
6795                        // If the process died while doing this, we will later
6796                        // do the cleanup with the process death link.
6797                    }
6798                }
6799            }
6800
6801            if (changed) {
6802                updateOomAdjLocked();
6803            }
6804        }
6805    }
6806
6807    // =========================================================
6808    // PERMISSIONS
6809    // =========================================================
6810
6811    static class PermissionController extends IPermissionController.Stub {
6812        ActivityManagerService mActivityManagerService;
6813        PermissionController(ActivityManagerService activityManagerService) {
6814            mActivityManagerService = activityManagerService;
6815        }
6816
6817        @Override
6818        public boolean checkPermission(String permission, int pid, int uid) {
6819            return mActivityManagerService.checkPermission(permission, pid,
6820                    uid) == PackageManager.PERMISSION_GRANTED;
6821        }
6822    }
6823
6824    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6825        @Override
6826        public int checkComponentPermission(String permission, int pid, int uid,
6827                int owningUid, boolean exported) {
6828            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6829                    owningUid, exported);
6830        }
6831
6832        @Override
6833        public Object getAMSLock() {
6834            return ActivityManagerService.this;
6835        }
6836    }
6837
6838    /**
6839     * This can be called with or without the global lock held.
6840     */
6841    int checkComponentPermission(String permission, int pid, int uid,
6842            int owningUid, boolean exported) {
6843        // We might be performing an operation on behalf of an indirect binder
6844        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6845        // client identity accordingly before proceeding.
6846        Identity tlsIdentity = sCallerIdentity.get();
6847        if (tlsIdentity != null) {
6848            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6849                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6850            uid = tlsIdentity.uid;
6851            pid = tlsIdentity.pid;
6852        }
6853
6854        if (pid == MY_PID) {
6855            return PackageManager.PERMISSION_GRANTED;
6856        }
6857
6858        return ActivityManager.checkComponentPermission(permission, uid,
6859                owningUid, exported);
6860    }
6861
6862    /**
6863     * As the only public entry point for permissions checking, this method
6864     * can enforce the semantic that requesting a check on a null global
6865     * permission is automatically denied.  (Internally a null permission
6866     * string is used when calling {@link #checkComponentPermission} in cases
6867     * when only uid-based security is needed.)
6868     *
6869     * This can be called with or without the global lock held.
6870     */
6871    @Override
6872    public int checkPermission(String permission, int pid, int uid) {
6873        if (permission == null) {
6874            return PackageManager.PERMISSION_DENIED;
6875        }
6876        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6877    }
6878
6879    /**
6880     * Binder IPC calls go through the public entry point.
6881     * This can be called with or without the global lock held.
6882     */
6883    int checkCallingPermission(String permission) {
6884        return checkPermission(permission,
6885                Binder.getCallingPid(),
6886                UserHandle.getAppId(Binder.getCallingUid()));
6887    }
6888
6889    /**
6890     * This can be called with or without the global lock held.
6891     */
6892    void enforceCallingPermission(String permission, String func) {
6893        if (checkCallingPermission(permission)
6894                == PackageManager.PERMISSION_GRANTED) {
6895            return;
6896        }
6897
6898        String msg = "Permission Denial: " + func + " from pid="
6899                + Binder.getCallingPid()
6900                + ", uid=" + Binder.getCallingUid()
6901                + " requires " + permission;
6902        Slog.w(TAG, msg);
6903        throw new SecurityException(msg);
6904    }
6905
6906    /**
6907     * Determine if UID is holding permissions required to access {@link Uri} in
6908     * the given {@link ProviderInfo}. Final permission checking is always done
6909     * in {@link ContentProvider}.
6910     */
6911    private final boolean checkHoldingPermissionsLocked(
6912            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6913        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6914                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6915        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6916            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6917                    != PERMISSION_GRANTED) {
6918                return false;
6919            }
6920        }
6921        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6922    }
6923
6924    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6925            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6926        if (pi.applicationInfo.uid == uid) {
6927            return true;
6928        } else if (!pi.exported) {
6929            return false;
6930        }
6931
6932        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6933        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6934        try {
6935            // check if target holds top-level <provider> permissions
6936            if (!readMet && pi.readPermission != null && considerUidPermissions
6937                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6938                readMet = true;
6939            }
6940            if (!writeMet && pi.writePermission != null && considerUidPermissions
6941                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6942                writeMet = true;
6943            }
6944
6945            // track if unprotected read/write is allowed; any denied
6946            // <path-permission> below removes this ability
6947            boolean allowDefaultRead = pi.readPermission == null;
6948            boolean allowDefaultWrite = pi.writePermission == null;
6949
6950            // check if target holds any <path-permission> that match uri
6951            final PathPermission[] pps = pi.pathPermissions;
6952            if (pps != null) {
6953                final String path = grantUri.uri.getPath();
6954                int i = pps.length;
6955                while (i > 0 && (!readMet || !writeMet)) {
6956                    i--;
6957                    PathPermission pp = pps[i];
6958                    if (pp.match(path)) {
6959                        if (!readMet) {
6960                            final String pprperm = pp.getReadPermission();
6961                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6962                                    + pprperm + " for " + pp.getPath()
6963                                    + ": match=" + pp.match(path)
6964                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6965                            if (pprperm != null) {
6966                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6967                                        == PERMISSION_GRANTED) {
6968                                    readMet = true;
6969                                } else {
6970                                    allowDefaultRead = false;
6971                                }
6972                            }
6973                        }
6974                        if (!writeMet) {
6975                            final String ppwperm = pp.getWritePermission();
6976                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6977                                    + ppwperm + " for " + pp.getPath()
6978                                    + ": match=" + pp.match(path)
6979                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6980                            if (ppwperm != null) {
6981                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6982                                        == PERMISSION_GRANTED) {
6983                                    writeMet = true;
6984                                } else {
6985                                    allowDefaultWrite = false;
6986                                }
6987                            }
6988                        }
6989                    }
6990                }
6991            }
6992
6993            // grant unprotected <provider> read/write, if not blocked by
6994            // <path-permission> above
6995            if (allowDefaultRead) readMet = true;
6996            if (allowDefaultWrite) writeMet = true;
6997
6998        } catch (RemoteException e) {
6999            return false;
7000        }
7001
7002        return readMet && writeMet;
7003    }
7004
7005    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7006        ProviderInfo pi = null;
7007        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7008        if (cpr != null) {
7009            pi = cpr.info;
7010        } else {
7011            try {
7012                pi = AppGlobals.getPackageManager().resolveContentProvider(
7013                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7014            } catch (RemoteException ex) {
7015            }
7016        }
7017        return pi;
7018    }
7019
7020    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7021        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7022        if (targetUris != null) {
7023            return targetUris.get(grantUri);
7024        }
7025        return null;
7026    }
7027
7028    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7029            String targetPkg, int targetUid, GrantUri grantUri) {
7030        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7031        if (targetUris == null) {
7032            targetUris = Maps.newArrayMap();
7033            mGrantedUriPermissions.put(targetUid, targetUris);
7034        }
7035
7036        UriPermission perm = targetUris.get(grantUri);
7037        if (perm == null) {
7038            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7039            targetUris.put(grantUri, perm);
7040        }
7041
7042        return perm;
7043    }
7044
7045    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7046            final int modeFlags) {
7047        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7048        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7049                : UriPermission.STRENGTH_OWNED;
7050
7051        // Root gets to do everything.
7052        if (uid == 0) {
7053            return true;
7054        }
7055
7056        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7057        if (perms == null) return false;
7058
7059        // First look for exact match
7060        final UriPermission exactPerm = perms.get(grantUri);
7061        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7062            return true;
7063        }
7064
7065        // No exact match, look for prefixes
7066        final int N = perms.size();
7067        for (int i = 0; i < N; i++) {
7068            final UriPermission perm = perms.valueAt(i);
7069            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7070                    && perm.getStrength(modeFlags) >= minStrength) {
7071                return true;
7072            }
7073        }
7074
7075        return false;
7076    }
7077
7078    /**
7079     * @param uri This uri must NOT contain an embedded userId.
7080     * @param userId The userId in which the uri is to be resolved.
7081     */
7082    @Override
7083    public int checkUriPermission(Uri uri, int pid, int uid,
7084            final int modeFlags, int userId) {
7085        enforceNotIsolatedCaller("checkUriPermission");
7086
7087        // Another redirected-binder-call permissions check as in
7088        // {@link checkComponentPermission}.
7089        Identity tlsIdentity = sCallerIdentity.get();
7090        if (tlsIdentity != null) {
7091            uid = tlsIdentity.uid;
7092            pid = tlsIdentity.pid;
7093        }
7094
7095        // Our own process gets to do everything.
7096        if (pid == MY_PID) {
7097            return PackageManager.PERMISSION_GRANTED;
7098        }
7099        synchronized (this) {
7100            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7101                    ? PackageManager.PERMISSION_GRANTED
7102                    : PackageManager.PERMISSION_DENIED;
7103        }
7104    }
7105
7106    /**
7107     * Check if the targetPkg can be granted permission to access uri by
7108     * the callingUid using the given modeFlags.  Throws a security exception
7109     * if callingUid is not allowed to do this.  Returns the uid of the target
7110     * if the URI permission grant should be performed; returns -1 if it is not
7111     * needed (for example targetPkg already has permission to access the URI).
7112     * If you already know the uid of the target, you can supply it in
7113     * lastTargetUid else set that to -1.
7114     */
7115    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7116            final int modeFlags, int lastTargetUid) {
7117        if (!Intent.isAccessUriMode(modeFlags)) {
7118            return -1;
7119        }
7120
7121        if (targetPkg != null) {
7122            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7123                    "Checking grant " + targetPkg + " permission to " + grantUri);
7124        }
7125
7126        final IPackageManager pm = AppGlobals.getPackageManager();
7127
7128        // If this is not a content: uri, we can't do anything with it.
7129        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7130            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7131                    "Can't grant URI permission for non-content URI: " + grantUri);
7132            return -1;
7133        }
7134
7135        final String authority = grantUri.uri.getAuthority();
7136        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7137        if (pi == null) {
7138            Slog.w(TAG, "No content provider found for permission check: " +
7139                    grantUri.uri.toSafeString());
7140            return -1;
7141        }
7142
7143        int targetUid = lastTargetUid;
7144        if (targetUid < 0 && targetPkg != null) {
7145            try {
7146                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7147                if (targetUid < 0) {
7148                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7149                            "Can't grant URI permission no uid for: " + targetPkg);
7150                    return -1;
7151                }
7152            } catch (RemoteException ex) {
7153                return -1;
7154            }
7155        }
7156
7157        if (targetUid >= 0) {
7158            // First...  does the target actually need this permission?
7159            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7160                // No need to grant the target this permission.
7161                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7162                        "Target " + targetPkg + " already has full permission to " + grantUri);
7163                return -1;
7164            }
7165        } else {
7166            // First...  there is no target package, so can anyone access it?
7167            boolean allowed = pi.exported;
7168            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7169                if (pi.readPermission != null) {
7170                    allowed = false;
7171                }
7172            }
7173            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7174                if (pi.writePermission != null) {
7175                    allowed = false;
7176                }
7177            }
7178            if (allowed) {
7179                return -1;
7180            }
7181        }
7182
7183        /* There is a special cross user grant if:
7184         * - The target is on another user.
7185         * - Apps on the current user can access the uri without any uid permissions.
7186         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7187         * grant uri permissions.
7188         */
7189        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7190                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7191                modeFlags, false /*without considering the uid permissions*/);
7192
7193        // Second...  is the provider allowing granting of URI permissions?
7194        if (!specialCrossUserGrant) {
7195            if (!pi.grantUriPermissions) {
7196                throw new SecurityException("Provider " + pi.packageName
7197                        + "/" + pi.name
7198                        + " does not allow granting of Uri permissions (uri "
7199                        + grantUri + ")");
7200            }
7201            if (pi.uriPermissionPatterns != null) {
7202                final int N = pi.uriPermissionPatterns.length;
7203                boolean allowed = false;
7204                for (int i=0; i<N; i++) {
7205                    if (pi.uriPermissionPatterns[i] != null
7206                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7207                        allowed = true;
7208                        break;
7209                    }
7210                }
7211                if (!allowed) {
7212                    throw new SecurityException("Provider " + pi.packageName
7213                            + "/" + pi.name
7214                            + " does not allow granting of permission to path of Uri "
7215                            + grantUri);
7216                }
7217            }
7218        }
7219
7220        // Third...  does the caller itself have permission to access
7221        // this uri?
7222        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7223            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7224                // Require they hold a strong enough Uri permission
7225                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7226                    throw new SecurityException("Uid " + callingUid
7227                            + " does not have permission to uri " + grantUri);
7228                }
7229            }
7230        }
7231        return targetUid;
7232    }
7233
7234    /**
7235     * @param uri This uri must NOT contain an embedded userId.
7236     * @param userId The userId in which the uri is to be resolved.
7237     */
7238    @Override
7239    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7240            final int modeFlags, int userId) {
7241        enforceNotIsolatedCaller("checkGrantUriPermission");
7242        synchronized(this) {
7243            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7244                    new GrantUri(userId, uri, false), modeFlags, -1);
7245        }
7246    }
7247
7248    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7249            final int modeFlags, UriPermissionOwner owner) {
7250        if (!Intent.isAccessUriMode(modeFlags)) {
7251            return;
7252        }
7253
7254        // So here we are: the caller has the assumed permission
7255        // to the uri, and the target doesn't.  Let's now give this to
7256        // the target.
7257
7258        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7259                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7260
7261        final String authority = grantUri.uri.getAuthority();
7262        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7263        if (pi == null) {
7264            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7265            return;
7266        }
7267
7268        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7269            grantUri.prefix = true;
7270        }
7271        final UriPermission perm = findOrCreateUriPermissionLocked(
7272                pi.packageName, targetPkg, targetUid, grantUri);
7273        perm.grantModes(modeFlags, owner);
7274    }
7275
7276    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7277            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7278        if (targetPkg == null) {
7279            throw new NullPointerException("targetPkg");
7280        }
7281        int targetUid;
7282        final IPackageManager pm = AppGlobals.getPackageManager();
7283        try {
7284            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7285        } catch (RemoteException ex) {
7286            return;
7287        }
7288
7289        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7290                targetUid);
7291        if (targetUid < 0) {
7292            return;
7293        }
7294
7295        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7296                owner);
7297    }
7298
7299    static class NeededUriGrants extends ArrayList<GrantUri> {
7300        final String targetPkg;
7301        final int targetUid;
7302        final int flags;
7303
7304        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7305            this.targetPkg = targetPkg;
7306            this.targetUid = targetUid;
7307            this.flags = flags;
7308        }
7309    }
7310
7311    /**
7312     * Like checkGrantUriPermissionLocked, but takes an Intent.
7313     */
7314    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7315            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7316        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7317                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7318                + " clip=" + (intent != null ? intent.getClipData() : null)
7319                + " from " + intent + "; flags=0x"
7320                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7321
7322        if (targetPkg == null) {
7323            throw new NullPointerException("targetPkg");
7324        }
7325
7326        if (intent == null) {
7327            return null;
7328        }
7329        Uri data = intent.getData();
7330        ClipData clip = intent.getClipData();
7331        if (data == null && clip == null) {
7332            return null;
7333        }
7334        // Default userId for uris in the intent (if they don't specify it themselves)
7335        int contentUserHint = intent.getContentUserHint();
7336        if (contentUserHint == UserHandle.USER_CURRENT) {
7337            contentUserHint = UserHandle.getUserId(callingUid);
7338        }
7339        final IPackageManager pm = AppGlobals.getPackageManager();
7340        int targetUid;
7341        if (needed != null) {
7342            targetUid = needed.targetUid;
7343        } else {
7344            try {
7345                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7346            } catch (RemoteException ex) {
7347                return null;
7348            }
7349            if (targetUid < 0) {
7350                if (DEBUG_URI_PERMISSION) {
7351                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7352                            + " on user " + targetUserId);
7353                }
7354                return null;
7355            }
7356        }
7357        if (data != null) {
7358            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7359            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7360                    targetUid);
7361            if (targetUid > 0) {
7362                if (needed == null) {
7363                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7364                }
7365                needed.add(grantUri);
7366            }
7367        }
7368        if (clip != null) {
7369            for (int i=0; i<clip.getItemCount(); i++) {
7370                Uri uri = clip.getItemAt(i).getUri();
7371                if (uri != null) {
7372                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7373                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7374                            targetUid);
7375                    if (targetUid > 0) {
7376                        if (needed == null) {
7377                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7378                        }
7379                        needed.add(grantUri);
7380                    }
7381                } else {
7382                    Intent clipIntent = clip.getItemAt(i).getIntent();
7383                    if (clipIntent != null) {
7384                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7385                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7386                        if (newNeeded != null) {
7387                            needed = newNeeded;
7388                        }
7389                    }
7390                }
7391            }
7392        }
7393
7394        return needed;
7395    }
7396
7397    /**
7398     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7399     */
7400    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7401            UriPermissionOwner owner) {
7402        if (needed != null) {
7403            for (int i=0; i<needed.size(); i++) {
7404                GrantUri grantUri = needed.get(i);
7405                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7406                        grantUri, needed.flags, owner);
7407            }
7408        }
7409    }
7410
7411    void grantUriPermissionFromIntentLocked(int callingUid,
7412            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7413        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7414                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7415        if (needed == null) {
7416            return;
7417        }
7418
7419        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7420    }
7421
7422    /**
7423     * @param uri This uri must NOT contain an embedded userId.
7424     * @param userId The userId in which the uri is to be resolved.
7425     */
7426    @Override
7427    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7428            final int modeFlags, int userId) {
7429        enforceNotIsolatedCaller("grantUriPermission");
7430        GrantUri grantUri = new GrantUri(userId, uri, false);
7431        synchronized(this) {
7432            final ProcessRecord r = getRecordForAppLocked(caller);
7433            if (r == null) {
7434                throw new SecurityException("Unable to find app for caller "
7435                        + caller
7436                        + " when granting permission to uri " + grantUri);
7437            }
7438            if (targetPkg == null) {
7439                throw new IllegalArgumentException("null target");
7440            }
7441            if (grantUri == null) {
7442                throw new IllegalArgumentException("null uri");
7443            }
7444
7445            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7446                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7447                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7448                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7449
7450            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7451                    UserHandle.getUserId(r.uid));
7452        }
7453    }
7454
7455    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7456        if (perm.modeFlags == 0) {
7457            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7458                    perm.targetUid);
7459            if (perms != null) {
7460                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7461                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7462
7463                perms.remove(perm.uri);
7464                if (perms.isEmpty()) {
7465                    mGrantedUriPermissions.remove(perm.targetUid);
7466                }
7467            }
7468        }
7469    }
7470
7471    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7472        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7473
7474        final IPackageManager pm = AppGlobals.getPackageManager();
7475        final String authority = grantUri.uri.getAuthority();
7476        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7477        if (pi == null) {
7478            Slog.w(TAG, "No content provider found for permission revoke: "
7479                    + grantUri.toSafeString());
7480            return;
7481        }
7482
7483        // Does the caller have this permission on the URI?
7484        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7485            // Have they don't have direct access to the URI, then revoke any URI
7486            // permissions that have been granted to them.
7487            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7488            if (perms != null) {
7489                boolean persistChanged = false;
7490                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7491                    final UriPermission perm = it.next();
7492                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7493                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7494                        if (DEBUG_URI_PERMISSION)
7495                            Slog.v(TAG,
7496                                    "Revoking " + perm.targetUid + " permission to " + perm.uri);
7497                        persistChanged |= perm.revokeModes(
7498                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7499                        if (perm.modeFlags == 0) {
7500                            it.remove();
7501                        }
7502                    }
7503                }
7504                if (perms.isEmpty()) {
7505                    mGrantedUriPermissions.remove(callingUid);
7506                }
7507                if (persistChanged) {
7508                    schedulePersistUriGrants();
7509                }
7510            }
7511            return;
7512        }
7513
7514        boolean persistChanged = false;
7515
7516        // Go through all of the permissions and remove any that match.
7517        int N = mGrantedUriPermissions.size();
7518        for (int i = 0; i < N; i++) {
7519            final int targetUid = mGrantedUriPermissions.keyAt(i);
7520            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7521
7522            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7523                final UriPermission perm = it.next();
7524                if (perm.uri.sourceUserId == grantUri.sourceUserId
7525                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7526                    if (DEBUG_URI_PERMISSION)
7527                        Slog.v(TAG,
7528                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7529                    persistChanged |= perm.revokeModes(
7530                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7531                    if (perm.modeFlags == 0) {
7532                        it.remove();
7533                    }
7534                }
7535            }
7536
7537            if (perms.isEmpty()) {
7538                mGrantedUriPermissions.remove(targetUid);
7539                N--;
7540                i--;
7541            }
7542        }
7543
7544        if (persistChanged) {
7545            schedulePersistUriGrants();
7546        }
7547    }
7548
7549    /**
7550     * @param uri This uri must NOT contain an embedded userId.
7551     * @param userId The userId in which the uri is to be resolved.
7552     */
7553    @Override
7554    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7555            int userId) {
7556        enforceNotIsolatedCaller("revokeUriPermission");
7557        synchronized(this) {
7558            final ProcessRecord r = getRecordForAppLocked(caller);
7559            if (r == null) {
7560                throw new SecurityException("Unable to find app for caller "
7561                        + caller
7562                        + " when revoking permission to uri " + uri);
7563            }
7564            if (uri == null) {
7565                Slog.w(TAG, "revokeUriPermission: null uri");
7566                return;
7567            }
7568
7569            if (!Intent.isAccessUriMode(modeFlags)) {
7570                return;
7571            }
7572
7573            final IPackageManager pm = AppGlobals.getPackageManager();
7574            final String authority = uri.getAuthority();
7575            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7576            if (pi == null) {
7577                Slog.w(TAG, "No content provider found for permission revoke: "
7578                        + uri.toSafeString());
7579                return;
7580            }
7581
7582            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7583        }
7584    }
7585
7586    /**
7587     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7588     * given package.
7589     *
7590     * @param packageName Package name to match, or {@code null} to apply to all
7591     *            packages.
7592     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7593     *            to all users.
7594     * @param persistable If persistable grants should be removed.
7595     */
7596    private void removeUriPermissionsForPackageLocked(
7597            String packageName, int userHandle, boolean persistable) {
7598        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7599            throw new IllegalArgumentException("Must narrow by either package or user");
7600        }
7601
7602        boolean persistChanged = false;
7603
7604        int N = mGrantedUriPermissions.size();
7605        for (int i = 0; i < N; i++) {
7606            final int targetUid = mGrantedUriPermissions.keyAt(i);
7607            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7608
7609            // Only inspect grants matching user
7610            if (userHandle == UserHandle.USER_ALL
7611                    || userHandle == UserHandle.getUserId(targetUid)) {
7612                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7613                    final UriPermission perm = it.next();
7614
7615                    // Only inspect grants matching package
7616                    if (packageName == null || perm.sourcePkg.equals(packageName)
7617                            || perm.targetPkg.equals(packageName)) {
7618                        persistChanged |= perm.revokeModes(
7619                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7620
7621                        // Only remove when no modes remain; any persisted grants
7622                        // will keep this alive.
7623                        if (perm.modeFlags == 0) {
7624                            it.remove();
7625                        }
7626                    }
7627                }
7628
7629                if (perms.isEmpty()) {
7630                    mGrantedUriPermissions.remove(targetUid);
7631                    N--;
7632                    i--;
7633                }
7634            }
7635        }
7636
7637        if (persistChanged) {
7638            schedulePersistUriGrants();
7639        }
7640    }
7641
7642    @Override
7643    public IBinder newUriPermissionOwner(String name) {
7644        enforceNotIsolatedCaller("newUriPermissionOwner");
7645        synchronized(this) {
7646            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7647            return owner.getExternalTokenLocked();
7648        }
7649    }
7650
7651    /**
7652     * @param uri This uri must NOT contain an embedded userId.
7653     * @param sourceUserId The userId in which the uri is to be resolved.
7654     * @param targetUserId The userId of the app that receives the grant.
7655     */
7656    @Override
7657    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7658            final int modeFlags, int sourceUserId, int targetUserId) {
7659        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7660                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7661        synchronized(this) {
7662            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7663            if (owner == null) {
7664                throw new IllegalArgumentException("Unknown owner: " + token);
7665            }
7666            if (fromUid != Binder.getCallingUid()) {
7667                if (Binder.getCallingUid() != Process.myUid()) {
7668                    // Only system code can grant URI permissions on behalf
7669                    // of other users.
7670                    throw new SecurityException("nice try");
7671                }
7672            }
7673            if (targetPkg == null) {
7674                throw new IllegalArgumentException("null target");
7675            }
7676            if (uri == null) {
7677                throw new IllegalArgumentException("null uri");
7678            }
7679
7680            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7681                    modeFlags, owner, targetUserId);
7682        }
7683    }
7684
7685    /**
7686     * @param uri This uri must NOT contain an embedded userId.
7687     * @param userId The userId in which the uri is to be resolved.
7688     */
7689    @Override
7690    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7691        synchronized(this) {
7692            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7693            if (owner == null) {
7694                throw new IllegalArgumentException("Unknown owner: " + token);
7695            }
7696
7697            if (uri == null) {
7698                owner.removeUriPermissionsLocked(mode);
7699            } else {
7700                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7701            }
7702        }
7703    }
7704
7705    private void schedulePersistUriGrants() {
7706        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7707            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7708                    10 * DateUtils.SECOND_IN_MILLIS);
7709        }
7710    }
7711
7712    private void writeGrantedUriPermissions() {
7713        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7714
7715        // Snapshot permissions so we can persist without lock
7716        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7717        synchronized (this) {
7718            final int size = mGrantedUriPermissions.size();
7719            for (int i = 0; i < size; i++) {
7720                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7721                for (UriPermission perm : perms.values()) {
7722                    if (perm.persistedModeFlags != 0) {
7723                        persist.add(perm.snapshot());
7724                    }
7725                }
7726            }
7727        }
7728
7729        FileOutputStream fos = null;
7730        try {
7731            fos = mGrantFile.startWrite();
7732
7733            XmlSerializer out = new FastXmlSerializer();
7734            out.setOutput(fos, "utf-8");
7735            out.startDocument(null, true);
7736            out.startTag(null, TAG_URI_GRANTS);
7737            for (UriPermission.Snapshot perm : persist) {
7738                out.startTag(null, TAG_URI_GRANT);
7739                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7740                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7741                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7742                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7743                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7744                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7745                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7746                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7747                out.endTag(null, TAG_URI_GRANT);
7748            }
7749            out.endTag(null, TAG_URI_GRANTS);
7750            out.endDocument();
7751
7752            mGrantFile.finishWrite(fos);
7753        } catch (IOException e) {
7754            if (fos != null) {
7755                mGrantFile.failWrite(fos);
7756            }
7757        }
7758    }
7759
7760    private void readGrantedUriPermissionsLocked() {
7761        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7762
7763        final long now = System.currentTimeMillis();
7764
7765        FileInputStream fis = null;
7766        try {
7767            fis = mGrantFile.openRead();
7768            final XmlPullParser in = Xml.newPullParser();
7769            in.setInput(fis, null);
7770
7771            int type;
7772            while ((type = in.next()) != END_DOCUMENT) {
7773                final String tag = in.getName();
7774                if (type == START_TAG) {
7775                    if (TAG_URI_GRANT.equals(tag)) {
7776                        final int sourceUserId;
7777                        final int targetUserId;
7778                        final int userHandle = readIntAttribute(in,
7779                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7780                        if (userHandle != UserHandle.USER_NULL) {
7781                            // For backwards compatibility.
7782                            sourceUserId = userHandle;
7783                            targetUserId = userHandle;
7784                        } else {
7785                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7786                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7787                        }
7788                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7789                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7790                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7791                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7792                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7793                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7794
7795                        // Sanity check that provider still belongs to source package
7796                        final ProviderInfo pi = getProviderInfoLocked(
7797                                uri.getAuthority(), sourceUserId);
7798                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7799                            int targetUid = -1;
7800                            try {
7801                                targetUid = AppGlobals.getPackageManager()
7802                                        .getPackageUid(targetPkg, targetUserId);
7803                            } catch (RemoteException e) {
7804                            }
7805                            if (targetUid != -1) {
7806                                final UriPermission perm = findOrCreateUriPermissionLocked(
7807                                        sourcePkg, targetPkg, targetUid,
7808                                        new GrantUri(sourceUserId, uri, prefix));
7809                                perm.initPersistedModes(modeFlags, createdTime);
7810                            }
7811                        } else {
7812                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7813                                    + " but instead found " + pi);
7814                        }
7815                    }
7816                }
7817            }
7818        } catch (FileNotFoundException e) {
7819            // Missing grants is okay
7820        } catch (IOException e) {
7821            Log.wtf(TAG, "Failed reading Uri grants", e);
7822        } catch (XmlPullParserException e) {
7823            Log.wtf(TAG, "Failed reading Uri grants", e);
7824        } finally {
7825            IoUtils.closeQuietly(fis);
7826        }
7827    }
7828
7829    /**
7830     * @param uri This uri must NOT contain an embedded userId.
7831     * @param userId The userId in which the uri is to be resolved.
7832     */
7833    @Override
7834    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7835        enforceNotIsolatedCaller("takePersistableUriPermission");
7836
7837        Preconditions.checkFlagsArgument(modeFlags,
7838                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7839
7840        synchronized (this) {
7841            final int callingUid = Binder.getCallingUid();
7842            boolean persistChanged = false;
7843            GrantUri grantUri = new GrantUri(userId, uri, false);
7844
7845            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7846                    new GrantUri(userId, uri, false));
7847            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7848                    new GrantUri(userId, uri, true));
7849
7850            final boolean exactValid = (exactPerm != null)
7851                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7852            final boolean prefixValid = (prefixPerm != null)
7853                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7854
7855            if (!(exactValid || prefixValid)) {
7856                throw new SecurityException("No persistable permission grants found for UID "
7857                        + callingUid + " and Uri " + grantUri.toSafeString());
7858            }
7859
7860            if (exactValid) {
7861                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7862            }
7863            if (prefixValid) {
7864                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7865            }
7866
7867            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7868
7869            if (persistChanged) {
7870                schedulePersistUriGrants();
7871            }
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 releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7881        enforceNotIsolatedCaller("releasePersistableUriPermission");
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
7890            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7891                    new GrantUri(userId, uri, false));
7892            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7893                    new GrantUri(userId, uri, true));
7894            if (exactPerm == null && prefixPerm == null) {
7895                throw new SecurityException("No permission grants found for UID " + callingUid
7896                        + " and Uri " + uri.toSafeString());
7897            }
7898
7899            if (exactPerm != null) {
7900                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7901                removeUriPermissionIfNeededLocked(exactPerm);
7902            }
7903            if (prefixPerm != null) {
7904                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7905                removeUriPermissionIfNeededLocked(prefixPerm);
7906            }
7907
7908            if (persistChanged) {
7909                schedulePersistUriGrants();
7910            }
7911        }
7912    }
7913
7914    /**
7915     * Prune any older {@link UriPermission} for the given UID until outstanding
7916     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7917     *
7918     * @return if any mutations occured that require persisting.
7919     */
7920    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7921        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7922        if (perms == null) return false;
7923        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7924
7925        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7926        for (UriPermission perm : perms.values()) {
7927            if (perm.persistedModeFlags != 0) {
7928                persisted.add(perm);
7929            }
7930        }
7931
7932        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7933        if (trimCount <= 0) return false;
7934
7935        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7936        for (int i = 0; i < trimCount; i++) {
7937            final UriPermission perm = persisted.get(i);
7938
7939            if (DEBUG_URI_PERMISSION) {
7940                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7941            }
7942
7943            perm.releasePersistableModes(~0);
7944            removeUriPermissionIfNeededLocked(perm);
7945        }
7946
7947        return true;
7948    }
7949
7950    @Override
7951    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7952            String packageName, boolean incoming) {
7953        enforceNotIsolatedCaller("getPersistedUriPermissions");
7954        Preconditions.checkNotNull(packageName, "packageName");
7955
7956        final int callingUid = Binder.getCallingUid();
7957        final IPackageManager pm = AppGlobals.getPackageManager();
7958        try {
7959            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7960            if (packageUid != callingUid) {
7961                throw new SecurityException(
7962                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7963            }
7964        } catch (RemoteException e) {
7965            throw new SecurityException("Failed to verify package name ownership");
7966        }
7967
7968        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7969        synchronized (this) {
7970            if (incoming) {
7971                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7972                        callingUid);
7973                if (perms == null) {
7974                    Slog.w(TAG, "No permission grants found for " + packageName);
7975                } else {
7976                    for (UriPermission perm : perms.values()) {
7977                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7978                            result.add(perm.buildPersistedPublicApiObject());
7979                        }
7980                    }
7981                }
7982            } else {
7983                final int size = mGrantedUriPermissions.size();
7984                for (int i = 0; i < size; i++) {
7985                    final ArrayMap<GrantUri, UriPermission> perms =
7986                            mGrantedUriPermissions.valueAt(i);
7987                    for (UriPermission perm : perms.values()) {
7988                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7989                            result.add(perm.buildPersistedPublicApiObject());
7990                        }
7991                    }
7992                }
7993            }
7994        }
7995        return new ParceledListSlice<android.content.UriPermission>(result);
7996    }
7997
7998    @Override
7999    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8000        synchronized (this) {
8001            ProcessRecord app =
8002                who != null ? getRecordForAppLocked(who) : null;
8003            if (app == null) return;
8004
8005            Message msg = Message.obtain();
8006            msg.what = WAIT_FOR_DEBUGGER_MSG;
8007            msg.obj = app;
8008            msg.arg1 = waiting ? 1 : 0;
8009            mHandler.sendMessage(msg);
8010        }
8011    }
8012
8013    @Override
8014    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8015        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8016        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8017        outInfo.availMem = Process.getFreeMemory();
8018        outInfo.totalMem = Process.getTotalMemory();
8019        outInfo.threshold = homeAppMem;
8020        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8021        outInfo.hiddenAppThreshold = cachedAppMem;
8022        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8023                ProcessList.SERVICE_ADJ);
8024        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8025                ProcessList.VISIBLE_APP_ADJ);
8026        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8027                ProcessList.FOREGROUND_APP_ADJ);
8028    }
8029
8030    // =========================================================
8031    // TASK MANAGEMENT
8032    // =========================================================
8033
8034    @Override
8035    public List<IAppTask> getAppTasks(String callingPackage) {
8036        int callingUid = Binder.getCallingUid();
8037        long ident = Binder.clearCallingIdentity();
8038
8039        synchronized(this) {
8040            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8041            try {
8042                if (localLOGV) Slog.v(TAG, "getAppTasks");
8043
8044                final int N = mRecentTasks.size();
8045                for (int i = 0; i < N; i++) {
8046                    TaskRecord tr = mRecentTasks.get(i);
8047                    // Skip tasks that do not match the caller.  We don't need to verify
8048                    // callingPackage, because we are also limiting to callingUid and know
8049                    // that will limit to the correct security sandbox.
8050                    if (tr.effectiveUid != callingUid) {
8051                        continue;
8052                    }
8053                    Intent intent = tr.getBaseIntent();
8054                    if (intent == null ||
8055                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8056                        continue;
8057                    }
8058                    ActivityManager.RecentTaskInfo taskInfo =
8059                            createRecentTaskInfoFromTaskRecord(tr);
8060                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8061                    list.add(taskImpl);
8062                }
8063            } finally {
8064                Binder.restoreCallingIdentity(ident);
8065            }
8066            return list;
8067        }
8068    }
8069
8070    @Override
8071    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8072        final int callingUid = Binder.getCallingUid();
8073        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8074
8075        synchronized(this) {
8076            if (localLOGV) Slog.v(
8077                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8078
8079            final boolean allowed = checkCallingPermission(
8080                    android.Manifest.permission.GET_TASKS)
8081                    == PackageManager.PERMISSION_GRANTED;
8082            if (!allowed) {
8083                Slog.w(TAG, "getTasks: caller " + callingUid
8084                        + " does not hold GET_TASKS; limiting output");
8085            }
8086
8087            // TODO: Improve with MRU list from all ActivityStacks.
8088            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8089        }
8090
8091        return list;
8092    }
8093
8094    TaskRecord getMostRecentTask() {
8095        return mRecentTasks.get(0);
8096    }
8097
8098    /**
8099     * Creates a new RecentTaskInfo from a TaskRecord.
8100     */
8101    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8102        // Update the task description to reflect any changes in the task stack
8103        tr.updateTaskDescription();
8104
8105        // Compose the recent task info
8106        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8107        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8108        rti.persistentId = tr.taskId;
8109        rti.baseIntent = new Intent(tr.getBaseIntent());
8110        rti.origActivity = tr.origActivity;
8111        rti.description = tr.lastDescription;
8112        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8113        rti.userId = tr.userId;
8114        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8115        rti.firstActiveTime = tr.firstActiveTime;
8116        rti.lastActiveTime = tr.lastActiveTime;
8117        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8118        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8119        return rti;
8120    }
8121
8122    @Override
8123    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8124        final int callingUid = Binder.getCallingUid();
8125        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8126                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8127
8128        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8129        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8130        synchronized (this) {
8131            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8132                    == PackageManager.PERMISSION_GRANTED;
8133            if (!allowed) {
8134                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8135                        + " does not hold GET_TASKS; limiting output");
8136            }
8137            final boolean detailed = checkCallingPermission(
8138                    android.Manifest.permission.GET_DETAILED_TASKS)
8139                    == PackageManager.PERMISSION_GRANTED;
8140
8141            final int N = mRecentTasks.size();
8142            ArrayList<ActivityManager.RecentTaskInfo> res
8143                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8144                            maxNum < N ? maxNum : N);
8145
8146            final Set<Integer> includedUsers;
8147            if (includeProfiles) {
8148                includedUsers = getProfileIdsLocked(userId);
8149            } else {
8150                includedUsers = new HashSet<Integer>();
8151            }
8152            includedUsers.add(Integer.valueOf(userId));
8153
8154            for (int i=0; i<N && maxNum > 0; i++) {
8155                TaskRecord tr = mRecentTasks.get(i);
8156                // Only add calling user or related users recent tasks
8157                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8158                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8159                    continue;
8160                }
8161
8162                // Return the entry if desired by the caller.  We always return
8163                // the first entry, because callers always expect this to be the
8164                // foreground app.  We may filter others if the caller has
8165                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8166                // we should exclude the entry.
8167
8168                if (i == 0
8169                        || withExcluded
8170                        || (tr.intent == null)
8171                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8172                                == 0)) {
8173                    if (!allowed) {
8174                        // If the caller doesn't have the GET_TASKS permission, then only
8175                        // allow them to see a small subset of tasks -- their own and home.
8176                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8177                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8178                            continue;
8179                        }
8180                    }
8181                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8182                        if (tr.stack != null && tr.stack.isHomeStack()) {
8183                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8184                            continue;
8185                        }
8186                    }
8187                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8188                        // Don't include auto remove tasks that are finished or finishing.
8189                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8190                                + tr);
8191                        continue;
8192                    }
8193                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8194                            && !tr.isAvailable) {
8195                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8196                        continue;
8197                    }
8198
8199                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8200                    if (!detailed) {
8201                        rti.baseIntent.replaceExtras((Bundle)null);
8202                    }
8203
8204                    res.add(rti);
8205                    maxNum--;
8206                }
8207            }
8208            return res;
8209        }
8210    }
8211
8212    private TaskRecord recentTaskForIdLocked(int id) {
8213        final int N = mRecentTasks.size();
8214            for (int i=0; i<N; i++) {
8215                TaskRecord tr = mRecentTasks.get(i);
8216                if (tr.taskId == id) {
8217                    return tr;
8218                }
8219            }
8220            return null;
8221    }
8222
8223    @Override
8224    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8225        synchronized (this) {
8226            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8227                    "getTaskThumbnail()");
8228            TaskRecord tr = recentTaskForIdLocked(id);
8229            if (tr != null) {
8230                return tr.getTaskThumbnailLocked();
8231            }
8232        }
8233        return null;
8234    }
8235
8236    @Override
8237    public int addAppTask(IBinder activityToken, Intent intent,
8238            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8239        final int callingUid = Binder.getCallingUid();
8240        final long callingIdent = Binder.clearCallingIdentity();
8241
8242        try {
8243            synchronized (this) {
8244                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8245                if (r == null) {
8246                    throw new IllegalArgumentException("Activity does not exist; token="
8247                            + activityToken);
8248                }
8249                ComponentName comp = intent.getComponent();
8250                if (comp == null) {
8251                    throw new IllegalArgumentException("Intent " + intent
8252                            + " must specify explicit component");
8253                }
8254                if (thumbnail.getWidth() != mThumbnailWidth
8255                        || thumbnail.getHeight() != mThumbnailHeight) {
8256                    throw new IllegalArgumentException("Bad thumbnail size: got "
8257                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8258                            + mThumbnailWidth + "x" + mThumbnailHeight);
8259                }
8260                if (intent.getSelector() != null) {
8261                    intent.setSelector(null);
8262                }
8263                if (intent.getSourceBounds() != null) {
8264                    intent.setSourceBounds(null);
8265                }
8266                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8267                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8268                        // The caller has added this as an auto-remove task...  that makes no
8269                        // sense, so turn off auto-remove.
8270                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8271                    }
8272                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8273                    // Must be a new task.
8274                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8275                }
8276                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8277                    mLastAddedTaskActivity = null;
8278                }
8279                ActivityInfo ainfo = mLastAddedTaskActivity;
8280                if (ainfo == null) {
8281                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8282                            comp, 0, UserHandle.getUserId(callingUid));
8283                    if (ainfo.applicationInfo.uid != callingUid) {
8284                        throw new SecurityException(
8285                                "Can't add task for another application: target uid="
8286                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8287                    }
8288                }
8289
8290                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8291                        intent, description);
8292
8293                int trimIdx = trimRecentsForTask(task, false);
8294                if (trimIdx >= 0) {
8295                    // If this would have caused a trim, then we'll abort because that
8296                    // means it would be added at the end of the list but then just removed.
8297                    return -1;
8298                }
8299
8300                final int N = mRecentTasks.size();
8301                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8302                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8303                    tr.removedFromRecents(mTaskPersister);
8304                }
8305
8306                task.inRecents = true;
8307                mRecentTasks.add(task);
8308                r.task.stack.addTask(task, false, false);
8309
8310                task.setLastThumbnail(thumbnail);
8311                task.freeLastThumbnail();
8312
8313                return task.taskId;
8314            }
8315        } finally {
8316            Binder.restoreCallingIdentity(callingIdent);
8317        }
8318    }
8319
8320    @Override
8321    public Point getAppTaskThumbnailSize() {
8322        synchronized (this) {
8323            return new Point(mThumbnailWidth,  mThumbnailHeight);
8324        }
8325    }
8326
8327    @Override
8328    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8329        synchronized (this) {
8330            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8331            if (r != null) {
8332                r.taskDescription = td;
8333                r.task.updateTaskDescription();
8334            }
8335        }
8336    }
8337
8338    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8339        mRecentTasks.remove(tr);
8340        tr.removedFromRecents(mTaskPersister);
8341        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8342        Intent baseIntent = new Intent(
8343                tr.intent != null ? tr.intent : tr.affinityIntent);
8344        ComponentName component = baseIntent.getComponent();
8345        if (component == null) {
8346            Slog.w(TAG, "Now component for base intent of task: " + tr);
8347            return;
8348        }
8349
8350        // Find any running services associated with this app.
8351        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8352
8353        if (killProcesses) {
8354            // Find any running processes associated with this app.
8355            final String pkg = component.getPackageName();
8356            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8357            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8358            for (int i=0; i<pmap.size(); i++) {
8359                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8360                for (int j=0; j<uids.size(); j++) {
8361                    ProcessRecord proc = uids.valueAt(j);
8362                    if (proc.userId != tr.userId) {
8363                        continue;
8364                    }
8365                    if (!proc.pkgList.containsKey(pkg)) {
8366                        continue;
8367                    }
8368                    procs.add(proc);
8369                }
8370            }
8371
8372            // Kill the running processes.
8373            for (int i=0; i<procs.size(); i++) {
8374                ProcessRecord pr = procs.get(i);
8375                if (pr == mHomeProcess) {
8376                    // Don't kill the home process along with tasks from the same package.
8377                    continue;
8378                }
8379                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8380                    pr.kill("remove task", true);
8381                } else {
8382                    pr.waitingToKill = "remove task";
8383                }
8384            }
8385        }
8386    }
8387
8388    /**
8389     * Removes the task with the specified task id.
8390     *
8391     * @param taskId Identifier of the task to be removed.
8392     * @param flags Additional operational flags.  May be 0 or
8393     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8394     * @return Returns true if the given task was found and removed.
8395     */
8396    private boolean removeTaskByIdLocked(int taskId, int flags) {
8397        TaskRecord tr = recentTaskForIdLocked(taskId);
8398        if (tr != null) {
8399            tr.removeTaskActivitiesLocked();
8400            cleanUpRemovedTaskLocked(tr, flags);
8401            if (tr.isPersistable) {
8402                notifyTaskPersisterLocked(null, true);
8403            }
8404            return true;
8405        }
8406        return false;
8407    }
8408
8409    @Override
8410    public boolean removeTask(int taskId, int flags) {
8411        synchronized (this) {
8412            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8413                    "removeTask()");
8414            long ident = Binder.clearCallingIdentity();
8415            try {
8416                return removeTaskByIdLocked(taskId, flags);
8417            } finally {
8418                Binder.restoreCallingIdentity(ident);
8419            }
8420        }
8421    }
8422
8423    /**
8424     * TODO: Add mController hook
8425     */
8426    @Override
8427    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8428        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8429                "moveTaskToFront()");
8430
8431        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8432        synchronized(this) {
8433            moveTaskToFrontLocked(taskId, flags, options);
8434        }
8435    }
8436
8437    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8438        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8439                Binder.getCallingUid(), "Task to front")) {
8440            ActivityOptions.abort(options);
8441            return;
8442        }
8443        final long origId = Binder.clearCallingIdentity();
8444        try {
8445            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8446            if (task == null) {
8447                return;
8448            }
8449            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8450                mStackSupervisor.showLockTaskToast();
8451                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8452                return;
8453            }
8454            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8455            if (prev != null && prev.isRecentsActivity()) {
8456                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8457            }
8458            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8459        } finally {
8460            Binder.restoreCallingIdentity(origId);
8461        }
8462        ActivityOptions.abort(options);
8463    }
8464
8465    @Override
8466    public void moveTaskToBack(int taskId) {
8467        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8468                "moveTaskToBack()");
8469
8470        synchronized(this) {
8471            TaskRecord tr = recentTaskForIdLocked(taskId);
8472            if (tr != null) {
8473                if (tr == mStackSupervisor.mLockTaskModeTask) {
8474                    mStackSupervisor.showLockTaskToast();
8475                    return;
8476                }
8477                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8478                ActivityStack stack = tr.stack;
8479                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8480                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8481                            Binder.getCallingUid(), "Task to back")) {
8482                        return;
8483                    }
8484                }
8485                final long origId = Binder.clearCallingIdentity();
8486                try {
8487                    stack.moveTaskToBackLocked(taskId, null);
8488                } finally {
8489                    Binder.restoreCallingIdentity(origId);
8490                }
8491            }
8492        }
8493    }
8494
8495    /**
8496     * Moves an activity, and all of the other activities within the same task, to the bottom
8497     * of the history stack.  The activity's order within the task is unchanged.
8498     *
8499     * @param token A reference to the activity we wish to move
8500     * @param nonRoot If false then this only works if the activity is the root
8501     *                of a task; if true it will work for any activity in a task.
8502     * @return Returns true if the move completed, false if not.
8503     */
8504    @Override
8505    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8506        enforceNotIsolatedCaller("moveActivityTaskToBack");
8507        synchronized(this) {
8508            final long origId = Binder.clearCallingIdentity();
8509            try {
8510                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8511                if (taskId >= 0) {
8512                    if ((mStackSupervisor.mLockTaskModeTask != null)
8513                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8514                        mStackSupervisor.showLockTaskToast();
8515                        return false;
8516                    }
8517                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8518                }
8519            } finally {
8520                Binder.restoreCallingIdentity(origId);
8521            }
8522        }
8523        return false;
8524    }
8525
8526    @Override
8527    public void moveTaskBackwards(int task) {
8528        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8529                "moveTaskBackwards()");
8530
8531        synchronized(this) {
8532            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8533                    Binder.getCallingUid(), "Task backwards")) {
8534                return;
8535            }
8536            final long origId = Binder.clearCallingIdentity();
8537            moveTaskBackwardsLocked(task);
8538            Binder.restoreCallingIdentity(origId);
8539        }
8540    }
8541
8542    private final void moveTaskBackwardsLocked(int task) {
8543        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8544    }
8545
8546    @Override
8547    public IBinder getHomeActivityToken() throws RemoteException {
8548        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8549                "getHomeActivityToken()");
8550        synchronized (this) {
8551            return mStackSupervisor.getHomeActivityToken();
8552        }
8553    }
8554
8555    @Override
8556    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8557            IActivityContainerCallback callback) throws RemoteException {
8558        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8559                "createActivityContainer()");
8560        synchronized (this) {
8561            if (parentActivityToken == null) {
8562                throw new IllegalArgumentException("parent token must not be null");
8563            }
8564            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8565            if (r == null) {
8566                return null;
8567            }
8568            if (callback == null) {
8569                throw new IllegalArgumentException("callback must not be null");
8570            }
8571            return mStackSupervisor.createActivityContainer(r, callback);
8572        }
8573    }
8574
8575    @Override
8576    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8577        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8578                "deleteActivityContainer()");
8579        synchronized (this) {
8580            mStackSupervisor.deleteActivityContainer(container);
8581        }
8582    }
8583
8584    @Override
8585    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8586            throws RemoteException {
8587        synchronized (this) {
8588            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8589            if (stack != null) {
8590                return stack.mActivityContainer;
8591            }
8592            return null;
8593        }
8594    }
8595
8596    @Override
8597    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8598        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8599                "moveTaskToStack()");
8600        if (stackId == HOME_STACK_ID) {
8601            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8602                    new RuntimeException("here").fillInStackTrace());
8603        }
8604        synchronized (this) {
8605            long ident = Binder.clearCallingIdentity();
8606            try {
8607                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8608                        + stackId + " toTop=" + toTop);
8609                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8610            } finally {
8611                Binder.restoreCallingIdentity(ident);
8612            }
8613        }
8614    }
8615
8616    @Override
8617    public void resizeStack(int stackBoxId, Rect bounds) {
8618        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8619                "resizeStackBox()");
8620        long ident = Binder.clearCallingIdentity();
8621        try {
8622            mWindowManager.resizeStack(stackBoxId, bounds);
8623        } finally {
8624            Binder.restoreCallingIdentity(ident);
8625        }
8626    }
8627
8628    @Override
8629    public List<StackInfo> getAllStackInfos() {
8630        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8631                "getAllStackInfos()");
8632        long ident = Binder.clearCallingIdentity();
8633        try {
8634            synchronized (this) {
8635                return mStackSupervisor.getAllStackInfosLocked();
8636            }
8637        } finally {
8638            Binder.restoreCallingIdentity(ident);
8639        }
8640    }
8641
8642    @Override
8643    public StackInfo getStackInfo(int stackId) {
8644        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8645                "getStackInfo()");
8646        long ident = Binder.clearCallingIdentity();
8647        try {
8648            synchronized (this) {
8649                return mStackSupervisor.getStackInfoLocked(stackId);
8650            }
8651        } finally {
8652            Binder.restoreCallingIdentity(ident);
8653        }
8654    }
8655
8656    @Override
8657    public boolean isInHomeStack(int taskId) {
8658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8659                "getStackInfo()");
8660        long ident = Binder.clearCallingIdentity();
8661        try {
8662            synchronized (this) {
8663                TaskRecord tr = recentTaskForIdLocked(taskId);
8664                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8665            }
8666        } finally {
8667            Binder.restoreCallingIdentity(ident);
8668        }
8669    }
8670
8671    @Override
8672    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8673        synchronized(this) {
8674            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8675        }
8676    }
8677
8678    private boolean isLockTaskAuthorized(String pkg) {
8679        final DevicePolicyManager dpm = (DevicePolicyManager)
8680                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8681        try {
8682            int uid = mContext.getPackageManager().getPackageUid(pkg,
8683                    Binder.getCallingUserHandle().getIdentifier());
8684            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8685        } catch (NameNotFoundException e) {
8686            return false;
8687        }
8688    }
8689
8690    void startLockTaskMode(TaskRecord task) {
8691        final String pkg;
8692        synchronized (this) {
8693            pkg = task.intent.getComponent().getPackageName();
8694        }
8695        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8696        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8697            final TaskRecord taskRecord = task;
8698            mHandler.post(new Runnable() {
8699                @Override
8700                public void run() {
8701                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8702                }
8703            });
8704            return;
8705        }
8706        long ident = Binder.clearCallingIdentity();
8707        try {
8708            synchronized (this) {
8709                // Since we lost lock on task, make sure it is still there.
8710                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8711                if (task != null) {
8712                    if (!isSystemInitiated
8713                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8714                        throw new IllegalArgumentException("Invalid task, not in foreground");
8715                    }
8716                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8717                }
8718            }
8719        } finally {
8720            Binder.restoreCallingIdentity(ident);
8721        }
8722    }
8723
8724    @Override
8725    public void startLockTaskMode(int taskId) {
8726        final TaskRecord task;
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            synchronized (this) {
8730                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8731            }
8732        } finally {
8733            Binder.restoreCallingIdentity(ident);
8734        }
8735        if (task != null) {
8736            startLockTaskMode(task);
8737        }
8738    }
8739
8740    @Override
8741    public void startLockTaskMode(IBinder token) {
8742        final TaskRecord task;
8743        long ident = Binder.clearCallingIdentity();
8744        try {
8745            synchronized (this) {
8746                final ActivityRecord r = ActivityRecord.forToken(token);
8747                if (r == null) {
8748                    return;
8749                }
8750                task = r.task;
8751            }
8752        } finally {
8753            Binder.restoreCallingIdentity(ident);
8754        }
8755        if (task != null) {
8756            startLockTaskMode(task);
8757        }
8758    }
8759
8760    @Override
8761    public void startLockTaskModeOnCurrent() throws RemoteException {
8762        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8763                "startLockTaskModeOnCurrent");
8764        ActivityRecord r = null;
8765        synchronized (this) {
8766            r = mStackSupervisor.topRunningActivityLocked();
8767        }
8768        startLockTaskMode(r.task);
8769    }
8770
8771    @Override
8772    public void stopLockTaskMode() {
8773        // Verify that the user matches the package of the intent for the TaskRecord
8774        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8775        // and stopLockTaskMode.
8776        final int callingUid = Binder.getCallingUid();
8777        if (callingUid != Process.SYSTEM_UID) {
8778            try {
8779                String pkg =
8780                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8781                int uid = mContext.getPackageManager().getPackageUid(pkg,
8782                        Binder.getCallingUserHandle().getIdentifier());
8783                if (uid != callingUid) {
8784                    throw new SecurityException("Invalid uid, expected " + uid);
8785                }
8786            } catch (NameNotFoundException e) {
8787                Log.d(TAG, "stopLockTaskMode " + e);
8788                return;
8789            }
8790        }
8791        long ident = Binder.clearCallingIdentity();
8792        try {
8793            Log.d(TAG, "stopLockTaskMode");
8794            // Stop lock task
8795            synchronized (this) {
8796                mStackSupervisor.setLockTaskModeLocked(null, false);
8797            }
8798        } finally {
8799            Binder.restoreCallingIdentity(ident);
8800        }
8801    }
8802
8803    @Override
8804    public void stopLockTaskModeOnCurrent() throws RemoteException {
8805        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8806                "stopLockTaskModeOnCurrent");
8807        long ident = Binder.clearCallingIdentity();
8808        try {
8809            stopLockTaskMode();
8810        } finally {
8811            Binder.restoreCallingIdentity(ident);
8812        }
8813    }
8814
8815    @Override
8816    public boolean isInLockTaskMode() {
8817        synchronized (this) {
8818            return mStackSupervisor.isInLockTaskMode();
8819        }
8820    }
8821
8822    // =========================================================
8823    // CONTENT PROVIDERS
8824    // =========================================================
8825
8826    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8827        List<ProviderInfo> providers = null;
8828        try {
8829            providers = AppGlobals.getPackageManager().
8830                queryContentProviders(app.processName, app.uid,
8831                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8832        } catch (RemoteException ex) {
8833        }
8834        if (DEBUG_MU)
8835            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8836        int userId = app.userId;
8837        if (providers != null) {
8838            int N = providers.size();
8839            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8840            for (int i=0; i<N; i++) {
8841                ProviderInfo cpi =
8842                    (ProviderInfo)providers.get(i);
8843                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8844                        cpi.name, cpi.flags);
8845                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8846                    // This is a singleton provider, but a user besides the
8847                    // default user is asking to initialize a process it runs
8848                    // in...  well, no, it doesn't actually run in this process,
8849                    // it runs in the process of the default user.  Get rid of it.
8850                    providers.remove(i);
8851                    N--;
8852                    i--;
8853                    continue;
8854                }
8855
8856                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8857                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8858                if (cpr == null) {
8859                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8860                    mProviderMap.putProviderByClass(comp, cpr);
8861                }
8862                if (DEBUG_MU)
8863                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8864                app.pubProviders.put(cpi.name, cpr);
8865                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8866                    // Don't add this if it is a platform component that is marked
8867                    // to run in multiple processes, because this is actually
8868                    // part of the framework so doesn't make sense to track as a
8869                    // separate apk in the process.
8870                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8871                            mProcessStats);
8872                }
8873                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8874            }
8875        }
8876        return providers;
8877    }
8878
8879    /**
8880     * Check if {@link ProcessRecord} has a possible chance at accessing the
8881     * given {@link ProviderInfo}. Final permission checking is always done
8882     * in {@link ContentProvider}.
8883     */
8884    private final String checkContentProviderPermissionLocked(
8885            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8886        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8887        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8888        boolean checkedGrants = false;
8889        if (checkUser) {
8890            // Looking for cross-user grants before enforcing the typical cross-users permissions
8891            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8892            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8893                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8894                    return null;
8895                }
8896                checkedGrants = true;
8897            }
8898            userId = handleIncomingUser(callingPid, callingUid, userId,
8899                    false, ALLOW_NON_FULL,
8900                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8901            if (userId != tmpTargetUserId) {
8902                // When we actually went to determine the final targer user ID, this ended
8903                // up different than our initial check for the authority.  This is because
8904                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8905                // SELF.  So we need to re-check the grants again.
8906                checkedGrants = false;
8907            }
8908        }
8909        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8910                cpi.applicationInfo.uid, cpi.exported)
8911                == PackageManager.PERMISSION_GRANTED) {
8912            return null;
8913        }
8914        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8915                cpi.applicationInfo.uid, cpi.exported)
8916                == PackageManager.PERMISSION_GRANTED) {
8917            return null;
8918        }
8919
8920        PathPermission[] pps = cpi.pathPermissions;
8921        if (pps != null) {
8922            int i = pps.length;
8923            while (i > 0) {
8924                i--;
8925                PathPermission pp = pps[i];
8926                String pprperm = pp.getReadPermission();
8927                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8928                        cpi.applicationInfo.uid, cpi.exported)
8929                        == PackageManager.PERMISSION_GRANTED) {
8930                    return null;
8931                }
8932                String ppwperm = pp.getWritePermission();
8933                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8934                        cpi.applicationInfo.uid, cpi.exported)
8935                        == PackageManager.PERMISSION_GRANTED) {
8936                    return null;
8937                }
8938            }
8939        }
8940        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8941            return null;
8942        }
8943
8944        String msg;
8945        if (!cpi.exported) {
8946            msg = "Permission Denial: opening provider " + cpi.name
8947                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8948                    + ", uid=" + callingUid + ") that is not exported from uid "
8949                    + cpi.applicationInfo.uid;
8950        } else {
8951            msg = "Permission Denial: opening provider " + cpi.name
8952                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8953                    + ", uid=" + callingUid + ") requires "
8954                    + cpi.readPermission + " or " + cpi.writePermission;
8955        }
8956        Slog.w(TAG, msg);
8957        return msg;
8958    }
8959
8960    /**
8961     * Returns if the ContentProvider has granted a uri to callingUid
8962     */
8963    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8964        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8965        if (perms != null) {
8966            for (int i=perms.size()-1; i>=0; i--) {
8967                GrantUri grantUri = perms.keyAt(i);
8968                if (grantUri.sourceUserId == userId || !checkUser) {
8969                    if (matchesProvider(grantUri.uri, cpi)) {
8970                        return true;
8971                    }
8972                }
8973            }
8974        }
8975        return false;
8976    }
8977
8978    /**
8979     * Returns true if the uri authority is one of the authorities specified in the provider.
8980     */
8981    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8982        String uriAuth = uri.getAuthority();
8983        String cpiAuth = cpi.authority;
8984        if (cpiAuth.indexOf(';') == -1) {
8985            return cpiAuth.equals(uriAuth);
8986        }
8987        String[] cpiAuths = cpiAuth.split(";");
8988        int length = cpiAuths.length;
8989        for (int i = 0; i < length; i++) {
8990            if (cpiAuths[i].equals(uriAuth)) return true;
8991        }
8992        return false;
8993    }
8994
8995    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8996            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8997        if (r != null) {
8998            for (int i=0; i<r.conProviders.size(); i++) {
8999                ContentProviderConnection conn = r.conProviders.get(i);
9000                if (conn.provider == cpr) {
9001                    if (DEBUG_PROVIDER) Slog.v(TAG,
9002                            "Adding provider requested by "
9003                            + r.processName + " from process "
9004                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9005                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9006                    if (stable) {
9007                        conn.stableCount++;
9008                        conn.numStableIncs++;
9009                    } else {
9010                        conn.unstableCount++;
9011                        conn.numUnstableIncs++;
9012                    }
9013                    return conn;
9014                }
9015            }
9016            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9017            if (stable) {
9018                conn.stableCount = 1;
9019                conn.numStableIncs = 1;
9020            } else {
9021                conn.unstableCount = 1;
9022                conn.numUnstableIncs = 1;
9023            }
9024            cpr.connections.add(conn);
9025            r.conProviders.add(conn);
9026            return conn;
9027        }
9028        cpr.addExternalProcessHandleLocked(externalProcessToken);
9029        return null;
9030    }
9031
9032    boolean decProviderCountLocked(ContentProviderConnection conn,
9033            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9034        if (conn != null) {
9035            cpr = conn.provider;
9036            if (DEBUG_PROVIDER) Slog.v(TAG,
9037                    "Removing provider requested by "
9038                    + conn.client.processName + " from process "
9039                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9040                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9041            if (stable) {
9042                conn.stableCount--;
9043            } else {
9044                conn.unstableCount--;
9045            }
9046            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9047                cpr.connections.remove(conn);
9048                conn.client.conProviders.remove(conn);
9049                return true;
9050            }
9051            return false;
9052        }
9053        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9054        return false;
9055    }
9056
9057    private void checkTime(long startTime, String where) {
9058        long now = SystemClock.elapsedRealtime();
9059        if ((now-startTime) > 1000) {
9060            // If we are taking more than a second, log about it.
9061            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9062        }
9063    }
9064
9065    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9066            String name, IBinder token, boolean stable, int userId) {
9067        ContentProviderRecord cpr;
9068        ContentProviderConnection conn = null;
9069        ProviderInfo cpi = null;
9070
9071        synchronized(this) {
9072            long startTime = SystemClock.elapsedRealtime();
9073
9074            ProcessRecord r = null;
9075            if (caller != null) {
9076                r = getRecordForAppLocked(caller);
9077                if (r == null) {
9078                    throw new SecurityException(
9079                            "Unable to find app for caller " + caller
9080                          + " (pid=" + Binder.getCallingPid()
9081                          + ") when getting content provider " + name);
9082                }
9083            }
9084
9085            boolean checkCrossUser = true;
9086
9087            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9088
9089            // First check if this content provider has been published...
9090            cpr = mProviderMap.getProviderByName(name, userId);
9091            // If that didn't work, check if it exists for user 0 and then
9092            // verify that it's a singleton provider before using it.
9093            if (cpr == null && userId != UserHandle.USER_OWNER) {
9094                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9095                if (cpr != null) {
9096                    cpi = cpr.info;
9097                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9098                            cpi.name, cpi.flags)
9099                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9100                        userId = UserHandle.USER_OWNER;
9101                        checkCrossUser = false;
9102                    } else {
9103                        cpr = null;
9104                        cpi = null;
9105                    }
9106                }
9107            }
9108
9109            boolean providerRunning = cpr != null;
9110            if (providerRunning) {
9111                cpi = cpr.info;
9112                String msg;
9113                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9114                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9115                        != null) {
9116                    throw new SecurityException(msg);
9117                }
9118                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9119
9120                if (r != null && cpr.canRunHere(r)) {
9121                    // This provider has been published or is in the process
9122                    // of being published...  but it is also allowed to run
9123                    // in the caller's process, so don't make a connection
9124                    // and just let the caller instantiate its own instance.
9125                    ContentProviderHolder holder = cpr.newHolder(null);
9126                    // don't give caller the provider object, it needs
9127                    // to make its own.
9128                    holder.provider = null;
9129                    return holder;
9130                }
9131
9132                final long origId = Binder.clearCallingIdentity();
9133
9134                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9135
9136                // In this case the provider instance already exists, so we can
9137                // return it right away.
9138                conn = incProviderCountLocked(r, cpr, token, stable);
9139                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9140                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9141                        // If this is a perceptible app accessing the provider,
9142                        // make sure to count it as being accessed and thus
9143                        // back up on the LRU list.  This is good because
9144                        // content providers are often expensive to start.
9145                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9146                        updateLruProcessLocked(cpr.proc, false, null);
9147                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9148                    }
9149                }
9150
9151                if (cpr.proc != null) {
9152                    if (false) {
9153                        if (cpr.name.flattenToShortString().equals(
9154                                "com.android.providers.calendar/.CalendarProvider2")) {
9155                            Slog.v(TAG, "****************** KILLING "
9156                                + cpr.name.flattenToShortString());
9157                            Process.killProcess(cpr.proc.pid);
9158                        }
9159                    }
9160                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9161                    boolean success = updateOomAdjLocked(cpr.proc);
9162                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9163                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9164                    // NOTE: there is still a race here where a signal could be
9165                    // pending on the process even though we managed to update its
9166                    // adj level.  Not sure what to do about this, but at least
9167                    // the race is now smaller.
9168                    if (!success) {
9169                        // Uh oh...  it looks like the provider's process
9170                        // has been killed on us.  We need to wait for a new
9171                        // process to be started, and make sure its death
9172                        // doesn't kill our process.
9173                        Slog.i(TAG,
9174                                "Existing provider " + cpr.name.flattenToShortString()
9175                                + " is crashing; detaching " + r);
9176                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9177                        checkTime(startTime, "getContentProviderImpl: before appDied");
9178                        appDiedLocked(cpr.proc);
9179                        checkTime(startTime, "getContentProviderImpl: after appDied");
9180                        if (!lastRef) {
9181                            // This wasn't the last ref our process had on
9182                            // the provider...  we have now been killed, bail.
9183                            return null;
9184                        }
9185                        providerRunning = false;
9186                        conn = null;
9187                    }
9188                }
9189
9190                Binder.restoreCallingIdentity(origId);
9191            }
9192
9193            boolean singleton;
9194            if (!providerRunning) {
9195                try {
9196                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9197                    cpi = AppGlobals.getPackageManager().
9198                        resolveContentProvider(name,
9199                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9200                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9201                } catch (RemoteException ex) {
9202                }
9203                if (cpi == null) {
9204                    return null;
9205                }
9206                // If the provider is a singleton AND
9207                // (it's a call within the same user || the provider is a
9208                // privileged app)
9209                // Then allow connecting to the singleton provider
9210                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9211                        cpi.name, cpi.flags)
9212                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9213                if (singleton) {
9214                    userId = UserHandle.USER_OWNER;
9215                }
9216                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9217                checkTime(startTime, "getContentProviderImpl: got app info for user");
9218
9219                String msg;
9220                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9221                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9222                        != null) {
9223                    throw new SecurityException(msg);
9224                }
9225                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9226
9227                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9228                        && !cpi.processName.equals("system")) {
9229                    // If this content provider does not run in the system
9230                    // process, and the system is not yet ready to run other
9231                    // processes, then fail fast instead of hanging.
9232                    throw new IllegalArgumentException(
9233                            "Attempt to launch content provider before system ready");
9234                }
9235
9236                // Make sure that the user who owns this provider is started.  If not,
9237                // we don't want to allow it to run.
9238                if (mStartedUsers.get(userId) == null) {
9239                    Slog.w(TAG, "Unable to launch app "
9240                            + cpi.applicationInfo.packageName + "/"
9241                            + cpi.applicationInfo.uid + " for provider "
9242                            + name + ": user " + userId + " is stopped");
9243                    return null;
9244                }
9245
9246                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9247                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9248                cpr = mProviderMap.getProviderByClass(comp, userId);
9249                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9250                final boolean firstClass = cpr == null;
9251                if (firstClass) {
9252                    try {
9253                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9254                        ApplicationInfo ai =
9255                            AppGlobals.getPackageManager().
9256                                getApplicationInfo(
9257                                        cpi.applicationInfo.packageName,
9258                                        STOCK_PM_FLAGS, userId);
9259                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9260                        if (ai == null) {
9261                            Slog.w(TAG, "No package info for content provider "
9262                                    + cpi.name);
9263                            return null;
9264                        }
9265                        ai = getAppInfoForUser(ai, userId);
9266                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9267                    } catch (RemoteException ex) {
9268                        // pm is in same process, this will never happen.
9269                    }
9270                }
9271
9272                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9273
9274                if (r != null && cpr.canRunHere(r)) {
9275                    // If this is a multiprocess provider, then just return its
9276                    // info and allow the caller to instantiate it.  Only do
9277                    // this if the provider is the same user as the caller's
9278                    // process, or can run as root (so can be in any process).
9279                    return cpr.newHolder(null);
9280                }
9281
9282                if (DEBUG_PROVIDER) {
9283                    RuntimeException e = new RuntimeException("here");
9284                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9285                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9286                }
9287
9288                // This is single process, and our app is now connecting to it.
9289                // See if we are already in the process of launching this
9290                // provider.
9291                final int N = mLaunchingProviders.size();
9292                int i;
9293                for (i=0; i<N; i++) {
9294                    if (mLaunchingProviders.get(i) == cpr) {
9295                        break;
9296                    }
9297                }
9298
9299                // If the provider is not already being launched, then get it
9300                // started.
9301                if (i >= N) {
9302                    final long origId = Binder.clearCallingIdentity();
9303
9304                    try {
9305                        // Content provider is now in use, its package can't be stopped.
9306                        try {
9307                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9308                            AppGlobals.getPackageManager().setPackageStoppedState(
9309                                    cpr.appInfo.packageName, false, userId);
9310                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9311                        } catch (RemoteException e) {
9312                        } catch (IllegalArgumentException e) {
9313                            Slog.w(TAG, "Failed trying to unstop package "
9314                                    + cpr.appInfo.packageName + ": " + e);
9315                        }
9316
9317                        // Use existing process if already started
9318                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9319                        ProcessRecord proc = getProcessRecordLocked(
9320                                cpi.processName, cpr.appInfo.uid, false);
9321                        if (proc != null && proc.thread != null) {
9322                            if (DEBUG_PROVIDER) {
9323                                Slog.d(TAG, "Installing in existing process " + proc);
9324                            }
9325                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9326                            proc.pubProviders.put(cpi.name, cpr);
9327                            try {
9328                                proc.thread.scheduleInstallProvider(cpi);
9329                            } catch (RemoteException e) {
9330                            }
9331                        } else {
9332                            checkTime(startTime, "getContentProviderImpl: before start process");
9333                            proc = startProcessLocked(cpi.processName,
9334                                    cpr.appInfo, false, 0, "content provider",
9335                                    new ComponentName(cpi.applicationInfo.packageName,
9336                                            cpi.name), false, false, false);
9337                            checkTime(startTime, "getContentProviderImpl: after start process");
9338                            if (proc == null) {
9339                                Slog.w(TAG, "Unable to launch app "
9340                                        + cpi.applicationInfo.packageName + "/"
9341                                        + cpi.applicationInfo.uid + " for provider "
9342                                        + name + ": process is bad");
9343                                return null;
9344                            }
9345                        }
9346                        cpr.launchingApp = proc;
9347                        mLaunchingProviders.add(cpr);
9348                    } finally {
9349                        Binder.restoreCallingIdentity(origId);
9350                    }
9351                }
9352
9353                checkTime(startTime, "getContentProviderImpl: updating data structures");
9354
9355                // Make sure the provider is published (the same provider class
9356                // may be published under multiple names).
9357                if (firstClass) {
9358                    mProviderMap.putProviderByClass(comp, cpr);
9359                }
9360
9361                mProviderMap.putProviderByName(name, cpr);
9362                conn = incProviderCountLocked(r, cpr, token, stable);
9363                if (conn != null) {
9364                    conn.waiting = true;
9365                }
9366            }
9367            checkTime(startTime, "getContentProviderImpl: done!");
9368        }
9369
9370        // Wait for the provider to be published...
9371        synchronized (cpr) {
9372            while (cpr.provider == null) {
9373                if (cpr.launchingApp == null) {
9374                    Slog.w(TAG, "Unable to launch app "
9375                            + cpi.applicationInfo.packageName + "/"
9376                            + cpi.applicationInfo.uid + " for provider "
9377                            + name + ": launching app became null");
9378                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9379                            UserHandle.getUserId(cpi.applicationInfo.uid),
9380                            cpi.applicationInfo.packageName,
9381                            cpi.applicationInfo.uid, name);
9382                    return null;
9383                }
9384                try {
9385                    if (DEBUG_MU) {
9386                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9387                                + cpr.launchingApp);
9388                    }
9389                    if (conn != null) {
9390                        conn.waiting = true;
9391                    }
9392                    cpr.wait();
9393                } catch (InterruptedException ex) {
9394                } finally {
9395                    if (conn != null) {
9396                        conn.waiting = false;
9397                    }
9398                }
9399            }
9400        }
9401        return cpr != null ? cpr.newHolder(conn) : null;
9402    }
9403
9404    @Override
9405    public final ContentProviderHolder getContentProvider(
9406            IApplicationThread caller, String name, int userId, boolean stable) {
9407        enforceNotIsolatedCaller("getContentProvider");
9408        if (caller == null) {
9409            String msg = "null IApplicationThread when getting content provider "
9410                    + name;
9411            Slog.w(TAG, msg);
9412            throw new SecurityException(msg);
9413        }
9414        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9415        // with cross-user grant.
9416        return getContentProviderImpl(caller, name, null, stable, userId);
9417    }
9418
9419    public ContentProviderHolder getContentProviderExternal(
9420            String name, int userId, IBinder token) {
9421        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9422            "Do not have permission in call getContentProviderExternal()");
9423        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9424                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9425        return getContentProviderExternalUnchecked(name, token, userId);
9426    }
9427
9428    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9429            IBinder token, int userId) {
9430        return getContentProviderImpl(null, name, token, true, userId);
9431    }
9432
9433    /**
9434     * Drop a content provider from a ProcessRecord's bookkeeping
9435     */
9436    public void removeContentProvider(IBinder connection, boolean stable) {
9437        enforceNotIsolatedCaller("removeContentProvider");
9438        long ident = Binder.clearCallingIdentity();
9439        try {
9440            synchronized (this) {
9441                ContentProviderConnection conn;
9442                try {
9443                    conn = (ContentProviderConnection)connection;
9444                } catch (ClassCastException e) {
9445                    String msg ="removeContentProvider: " + connection
9446                            + " not a ContentProviderConnection";
9447                    Slog.w(TAG, msg);
9448                    throw new IllegalArgumentException(msg);
9449                }
9450                if (conn == null) {
9451                    throw new NullPointerException("connection is null");
9452                }
9453                if (decProviderCountLocked(conn, null, null, stable)) {
9454                    updateOomAdjLocked();
9455                }
9456            }
9457        } finally {
9458            Binder.restoreCallingIdentity(ident);
9459        }
9460    }
9461
9462    public void removeContentProviderExternal(String name, IBinder token) {
9463        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9464            "Do not have permission in call removeContentProviderExternal()");
9465        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9466    }
9467
9468    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9469        synchronized (this) {
9470            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9471            if(cpr == null) {
9472                //remove from mProvidersByClass
9473                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9474                return;
9475            }
9476
9477            //update content provider record entry info
9478            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9479            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9480            if (localCpr.hasExternalProcessHandles()) {
9481                if (localCpr.removeExternalProcessHandleLocked(token)) {
9482                    updateOomAdjLocked();
9483                } else {
9484                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9485                            + " with no external reference for token: "
9486                            + token + ".");
9487                }
9488            } else {
9489                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9490                        + " with no external references.");
9491            }
9492        }
9493    }
9494
9495    public final void publishContentProviders(IApplicationThread caller,
9496            List<ContentProviderHolder> providers) {
9497        if (providers == null) {
9498            return;
9499        }
9500
9501        enforceNotIsolatedCaller("publishContentProviders");
9502        synchronized (this) {
9503            final ProcessRecord r = getRecordForAppLocked(caller);
9504            if (DEBUG_MU)
9505                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9506            if (r == null) {
9507                throw new SecurityException(
9508                        "Unable to find app for caller " + caller
9509                      + " (pid=" + Binder.getCallingPid()
9510                      + ") when publishing content providers");
9511            }
9512
9513            final long origId = Binder.clearCallingIdentity();
9514
9515            final int N = providers.size();
9516            for (int i=0; i<N; i++) {
9517                ContentProviderHolder src = providers.get(i);
9518                if (src == null || src.info == null || src.provider == null) {
9519                    continue;
9520                }
9521                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9522                if (DEBUG_MU)
9523                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9524                if (dst != null) {
9525                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9526                    mProviderMap.putProviderByClass(comp, dst);
9527                    String names[] = dst.info.authority.split(";");
9528                    for (int j = 0; j < names.length; j++) {
9529                        mProviderMap.putProviderByName(names[j], dst);
9530                    }
9531
9532                    int NL = mLaunchingProviders.size();
9533                    int j;
9534                    for (j=0; j<NL; j++) {
9535                        if (mLaunchingProviders.get(j) == dst) {
9536                            mLaunchingProviders.remove(j);
9537                            j--;
9538                            NL--;
9539                        }
9540                    }
9541                    synchronized (dst) {
9542                        dst.provider = src.provider;
9543                        dst.proc = r;
9544                        dst.notifyAll();
9545                    }
9546                    updateOomAdjLocked(r);
9547                }
9548            }
9549
9550            Binder.restoreCallingIdentity(origId);
9551        }
9552    }
9553
9554    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9555        ContentProviderConnection conn;
9556        try {
9557            conn = (ContentProviderConnection)connection;
9558        } catch (ClassCastException e) {
9559            String msg ="refContentProvider: " + connection
9560                    + " not a ContentProviderConnection";
9561            Slog.w(TAG, msg);
9562            throw new IllegalArgumentException(msg);
9563        }
9564        if (conn == null) {
9565            throw new NullPointerException("connection is null");
9566        }
9567
9568        synchronized (this) {
9569            if (stable > 0) {
9570                conn.numStableIncs += stable;
9571            }
9572            stable = conn.stableCount + stable;
9573            if (stable < 0) {
9574                throw new IllegalStateException("stableCount < 0: " + stable);
9575            }
9576
9577            if (unstable > 0) {
9578                conn.numUnstableIncs += unstable;
9579            }
9580            unstable = conn.unstableCount + unstable;
9581            if (unstable < 0) {
9582                throw new IllegalStateException("unstableCount < 0: " + unstable);
9583            }
9584
9585            if ((stable+unstable) <= 0) {
9586                throw new IllegalStateException("ref counts can't go to zero here: stable="
9587                        + stable + " unstable=" + unstable);
9588            }
9589            conn.stableCount = stable;
9590            conn.unstableCount = unstable;
9591            return !conn.dead;
9592        }
9593    }
9594
9595    public void unstableProviderDied(IBinder connection) {
9596        ContentProviderConnection conn;
9597        try {
9598            conn = (ContentProviderConnection)connection;
9599        } catch (ClassCastException e) {
9600            String msg ="refContentProvider: " + connection
9601                    + " not a ContentProviderConnection";
9602            Slog.w(TAG, msg);
9603            throw new IllegalArgumentException(msg);
9604        }
9605        if (conn == null) {
9606            throw new NullPointerException("connection is null");
9607        }
9608
9609        // Safely retrieve the content provider associated with the connection.
9610        IContentProvider provider;
9611        synchronized (this) {
9612            provider = conn.provider.provider;
9613        }
9614
9615        if (provider == null) {
9616            // Um, yeah, we're way ahead of you.
9617            return;
9618        }
9619
9620        // Make sure the caller is being honest with us.
9621        if (provider.asBinder().pingBinder()) {
9622            // Er, no, still looks good to us.
9623            synchronized (this) {
9624                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9625                        + " says " + conn + " died, but we don't agree");
9626                return;
9627            }
9628        }
9629
9630        // Well look at that!  It's dead!
9631        synchronized (this) {
9632            if (conn.provider.provider != provider) {
9633                // But something changed...  good enough.
9634                return;
9635            }
9636
9637            ProcessRecord proc = conn.provider.proc;
9638            if (proc == null || proc.thread == null) {
9639                // Seems like the process is already cleaned up.
9640                return;
9641            }
9642
9643            // As far as we're concerned, this is just like receiving a
9644            // death notification...  just a bit prematurely.
9645            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9646                    + ") early provider death");
9647            final long ident = Binder.clearCallingIdentity();
9648            try {
9649                appDiedLocked(proc);
9650            } finally {
9651                Binder.restoreCallingIdentity(ident);
9652            }
9653        }
9654    }
9655
9656    @Override
9657    public void appNotRespondingViaProvider(IBinder connection) {
9658        enforceCallingPermission(
9659                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9660
9661        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9662        if (conn == null) {
9663            Slog.w(TAG, "ContentProviderConnection is null");
9664            return;
9665        }
9666
9667        final ProcessRecord host = conn.provider.proc;
9668        if (host == null) {
9669            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9670            return;
9671        }
9672
9673        final long token = Binder.clearCallingIdentity();
9674        try {
9675            appNotResponding(host, null, null, false, "ContentProvider not responding");
9676        } finally {
9677            Binder.restoreCallingIdentity(token);
9678        }
9679    }
9680
9681    public final void installSystemProviders() {
9682        List<ProviderInfo> providers;
9683        synchronized (this) {
9684            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9685            providers = generateApplicationProvidersLocked(app);
9686            if (providers != null) {
9687                for (int i=providers.size()-1; i>=0; i--) {
9688                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9689                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9690                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9691                                + ": not system .apk");
9692                        providers.remove(i);
9693                    }
9694                }
9695            }
9696        }
9697        if (providers != null) {
9698            mSystemThread.installSystemProviders(providers);
9699        }
9700
9701        mCoreSettingsObserver = new CoreSettingsObserver(this);
9702
9703        //mUsageStatsService.monitorPackages();
9704    }
9705
9706    /**
9707     * Allows apps to retrieve the MIME type of a URI.
9708     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9709     * users, then it does not need permission to access the ContentProvider.
9710     * Either, it needs cross-user uri grants.
9711     *
9712     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9713     *
9714     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9715     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9716     */
9717    public String getProviderMimeType(Uri uri, int userId) {
9718        enforceNotIsolatedCaller("getProviderMimeType");
9719        final String name = uri.getAuthority();
9720        int callingUid = Binder.getCallingUid();
9721        int callingPid = Binder.getCallingPid();
9722        long ident = 0;
9723        boolean clearedIdentity = false;
9724        userId = unsafeConvertIncomingUser(userId);
9725        if (canClearIdentity(callingPid, callingUid, userId)) {
9726            clearedIdentity = true;
9727            ident = Binder.clearCallingIdentity();
9728        }
9729        ContentProviderHolder holder = null;
9730        try {
9731            holder = getContentProviderExternalUnchecked(name, null, userId);
9732            if (holder != null) {
9733                return holder.provider.getType(uri);
9734            }
9735        } catch (RemoteException e) {
9736            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9737            return null;
9738        } finally {
9739            // We need to clear the identity to call removeContentProviderExternalUnchecked
9740            if (!clearedIdentity) {
9741                ident = Binder.clearCallingIdentity();
9742            }
9743            try {
9744                if (holder != null) {
9745                    removeContentProviderExternalUnchecked(name, null, userId);
9746                }
9747            } finally {
9748                Binder.restoreCallingIdentity(ident);
9749            }
9750        }
9751
9752        return null;
9753    }
9754
9755    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9756        if (UserHandle.getUserId(callingUid) == userId) {
9757            return true;
9758        }
9759        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9760                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9761                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9762                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9763                return true;
9764        }
9765        return false;
9766    }
9767
9768    // =========================================================
9769    // GLOBAL MANAGEMENT
9770    // =========================================================
9771
9772    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9773            boolean isolated, int isolatedUid) {
9774        String proc = customProcess != null ? customProcess : info.processName;
9775        BatteryStatsImpl.Uid.Proc ps = null;
9776        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9777        int uid = info.uid;
9778        if (isolated) {
9779            if (isolatedUid == 0) {
9780                int userId = UserHandle.getUserId(uid);
9781                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9782                while (true) {
9783                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9784                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9785                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9786                    }
9787                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9788                    mNextIsolatedProcessUid++;
9789                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9790                        // No process for this uid, use it.
9791                        break;
9792                    }
9793                    stepsLeft--;
9794                    if (stepsLeft <= 0) {
9795                        return null;
9796                    }
9797                }
9798            } else {
9799                // Special case for startIsolatedProcess (internal only), where
9800                // the uid of the isolated process is specified by the caller.
9801                uid = isolatedUid;
9802            }
9803        }
9804        return new ProcessRecord(stats, info, proc, uid);
9805    }
9806
9807    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9808            String abiOverride) {
9809        ProcessRecord app;
9810        if (!isolated) {
9811            app = getProcessRecordLocked(info.processName, info.uid, true);
9812        } else {
9813            app = null;
9814        }
9815
9816        if (app == null) {
9817            app = newProcessRecordLocked(info, null, isolated, 0);
9818            mProcessNames.put(info.processName, app.uid, app);
9819            if (isolated) {
9820                mIsolatedProcesses.put(app.uid, app);
9821            }
9822            updateLruProcessLocked(app, false, null);
9823            updateOomAdjLocked();
9824        }
9825
9826        // This package really, really can not be stopped.
9827        try {
9828            AppGlobals.getPackageManager().setPackageStoppedState(
9829                    info.packageName, false, UserHandle.getUserId(app.uid));
9830        } catch (RemoteException e) {
9831        } catch (IllegalArgumentException e) {
9832            Slog.w(TAG, "Failed trying to unstop package "
9833                    + info.packageName + ": " + e);
9834        }
9835
9836        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9837                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9838            app.persistent = true;
9839            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9840        }
9841        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9842            mPersistentStartingProcesses.add(app);
9843            startProcessLocked(app, "added application", app.processName, abiOverride,
9844                    null /* entryPoint */, null /* entryPointArgs */);
9845        }
9846
9847        return app;
9848    }
9849
9850    public void unhandledBack() {
9851        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9852                "unhandledBack()");
9853
9854        synchronized(this) {
9855            final long origId = Binder.clearCallingIdentity();
9856            try {
9857                getFocusedStack().unhandledBackLocked();
9858            } finally {
9859                Binder.restoreCallingIdentity(origId);
9860            }
9861        }
9862    }
9863
9864    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9865        enforceNotIsolatedCaller("openContentUri");
9866        final int userId = UserHandle.getCallingUserId();
9867        String name = uri.getAuthority();
9868        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9869        ParcelFileDescriptor pfd = null;
9870        if (cph != null) {
9871            // We record the binder invoker's uid in thread-local storage before
9872            // going to the content provider to open the file.  Later, in the code
9873            // that handles all permissions checks, we look for this uid and use
9874            // that rather than the Activity Manager's own uid.  The effect is that
9875            // we do the check against the caller's permissions even though it looks
9876            // to the content provider like the Activity Manager itself is making
9877            // the request.
9878            sCallerIdentity.set(new Identity(
9879                    Binder.getCallingPid(), Binder.getCallingUid()));
9880            try {
9881                pfd = cph.provider.openFile(null, uri, "r", null);
9882            } catch (FileNotFoundException e) {
9883                // do nothing; pfd will be returned null
9884            } finally {
9885                // Ensure that whatever happens, we clean up the identity state
9886                sCallerIdentity.remove();
9887            }
9888
9889            // We've got the fd now, so we're done with the provider.
9890            removeContentProviderExternalUnchecked(name, null, userId);
9891        } else {
9892            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9893        }
9894        return pfd;
9895    }
9896
9897    // Actually is sleeping or shutting down or whatever else in the future
9898    // is an inactive state.
9899    public boolean isSleepingOrShuttingDown() {
9900        return mSleeping || mShuttingDown;
9901    }
9902
9903    public boolean isSleeping() {
9904        return mSleeping;
9905    }
9906
9907    void goingToSleep() {
9908        synchronized(this) {
9909            mWentToSleep = true;
9910            updateEventDispatchingLocked();
9911            goToSleepIfNeededLocked();
9912        }
9913    }
9914
9915    void finishRunningVoiceLocked() {
9916        if (mRunningVoice) {
9917            mRunningVoice = false;
9918            goToSleepIfNeededLocked();
9919        }
9920    }
9921
9922    void goToSleepIfNeededLocked() {
9923        if (mWentToSleep && !mRunningVoice) {
9924            if (!mSleeping) {
9925                mSleeping = true;
9926                mStackSupervisor.goingToSleepLocked();
9927
9928                // Initialize the wake times of all processes.
9929                checkExcessivePowerUsageLocked(false);
9930                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9931                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9932                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9933            }
9934        }
9935    }
9936
9937    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9938        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9939            // Never persist the home stack.
9940            return;
9941        }
9942        mTaskPersister.wakeup(task, flush);
9943    }
9944
9945    @Override
9946    public boolean shutdown(int timeout) {
9947        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9948                != PackageManager.PERMISSION_GRANTED) {
9949            throw new SecurityException("Requires permission "
9950                    + android.Manifest.permission.SHUTDOWN);
9951        }
9952
9953        boolean timedout = false;
9954
9955        synchronized(this) {
9956            mShuttingDown = true;
9957            updateEventDispatchingLocked();
9958            timedout = mStackSupervisor.shutdownLocked(timeout);
9959        }
9960
9961        mAppOpsService.shutdown();
9962        if (mUsageStatsService != null) {
9963            mUsageStatsService.prepareShutdown();
9964        }
9965        mBatteryStatsService.shutdown();
9966        synchronized (this) {
9967            mProcessStats.shutdownLocked();
9968        }
9969        notifyTaskPersisterLocked(null, true);
9970
9971        return timedout;
9972    }
9973
9974    public final void activitySlept(IBinder token) {
9975        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9976
9977        final long origId = Binder.clearCallingIdentity();
9978
9979        synchronized (this) {
9980            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9981            if (r != null) {
9982                mStackSupervisor.activitySleptLocked(r);
9983            }
9984        }
9985
9986        Binder.restoreCallingIdentity(origId);
9987    }
9988
9989    void logLockScreen(String msg) {
9990        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9991                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9992                mWentToSleep + " mSleeping=" + mSleeping);
9993    }
9994
9995    private void comeOutOfSleepIfNeededLocked() {
9996        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9997            if (mSleeping) {
9998                mSleeping = false;
9999                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10000            }
10001        }
10002    }
10003
10004    void wakingUp() {
10005        synchronized(this) {
10006            mWentToSleep = false;
10007            updateEventDispatchingLocked();
10008            comeOutOfSleepIfNeededLocked();
10009        }
10010    }
10011
10012    void startRunningVoiceLocked() {
10013        if (!mRunningVoice) {
10014            mRunningVoice = true;
10015            comeOutOfSleepIfNeededLocked();
10016        }
10017    }
10018
10019    private void updateEventDispatchingLocked() {
10020        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10021    }
10022
10023    public void setLockScreenShown(boolean shown) {
10024        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10025                != PackageManager.PERMISSION_GRANTED) {
10026            throw new SecurityException("Requires permission "
10027                    + android.Manifest.permission.DEVICE_POWER);
10028        }
10029
10030        synchronized(this) {
10031            long ident = Binder.clearCallingIdentity();
10032            try {
10033                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10034                mLockScreenShown = shown;
10035                comeOutOfSleepIfNeededLocked();
10036            } finally {
10037                Binder.restoreCallingIdentity(ident);
10038            }
10039        }
10040    }
10041
10042    @Override
10043    public void stopAppSwitches() {
10044        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10045                != PackageManager.PERMISSION_GRANTED) {
10046            throw new SecurityException("Requires permission "
10047                    + android.Manifest.permission.STOP_APP_SWITCHES);
10048        }
10049
10050        synchronized(this) {
10051            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10052                    + APP_SWITCH_DELAY_TIME;
10053            mDidAppSwitch = false;
10054            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10055            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10056            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10057        }
10058    }
10059
10060    public void resumeAppSwitches() {
10061        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10062                != PackageManager.PERMISSION_GRANTED) {
10063            throw new SecurityException("Requires permission "
10064                    + android.Manifest.permission.STOP_APP_SWITCHES);
10065        }
10066
10067        synchronized(this) {
10068            // Note that we don't execute any pending app switches... we will
10069            // let those wait until either the timeout, or the next start
10070            // activity request.
10071            mAppSwitchesAllowedTime = 0;
10072        }
10073    }
10074
10075    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10076            String name) {
10077        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10078            return true;
10079        }
10080
10081        final int perm = checkComponentPermission(
10082                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10083                callingUid, -1, true);
10084        if (perm == PackageManager.PERMISSION_GRANTED) {
10085            return true;
10086        }
10087
10088        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10089        return false;
10090    }
10091
10092    public void setDebugApp(String packageName, boolean waitForDebugger,
10093            boolean persistent) {
10094        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10095                "setDebugApp()");
10096
10097        long ident = Binder.clearCallingIdentity();
10098        try {
10099            // Note that this is not really thread safe if there are multiple
10100            // callers into it at the same time, but that's not a situation we
10101            // care about.
10102            if (persistent) {
10103                final ContentResolver resolver = mContext.getContentResolver();
10104                Settings.Global.putString(
10105                    resolver, Settings.Global.DEBUG_APP,
10106                    packageName);
10107                Settings.Global.putInt(
10108                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10109                    waitForDebugger ? 1 : 0);
10110            }
10111
10112            synchronized (this) {
10113                if (!persistent) {
10114                    mOrigDebugApp = mDebugApp;
10115                    mOrigWaitForDebugger = mWaitForDebugger;
10116                }
10117                mDebugApp = packageName;
10118                mWaitForDebugger = waitForDebugger;
10119                mDebugTransient = !persistent;
10120                if (packageName != null) {
10121                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10122                            false, UserHandle.USER_ALL, "set debug app");
10123                }
10124            }
10125        } finally {
10126            Binder.restoreCallingIdentity(ident);
10127        }
10128    }
10129
10130    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10131        synchronized (this) {
10132            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10133            if (!isDebuggable) {
10134                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10135                    throw new SecurityException("Process not debuggable: " + app.packageName);
10136                }
10137            }
10138
10139            mOpenGlTraceApp = processName;
10140        }
10141    }
10142
10143    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10144        synchronized (this) {
10145            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10146            if (!isDebuggable) {
10147                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10148                    throw new SecurityException("Process not debuggable: " + app.packageName);
10149                }
10150            }
10151            mProfileApp = processName;
10152            mProfileFile = profilerInfo.profileFile;
10153            if (mProfileFd != null) {
10154                try {
10155                    mProfileFd.close();
10156                } catch (IOException e) {
10157                }
10158                mProfileFd = null;
10159            }
10160            mProfileFd = profilerInfo.profileFd;
10161            mSamplingInterval = profilerInfo.samplingInterval;
10162            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10163            mProfileType = 0;
10164        }
10165    }
10166
10167    @Override
10168    public void setAlwaysFinish(boolean enabled) {
10169        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10170                "setAlwaysFinish()");
10171
10172        Settings.Global.putInt(
10173                mContext.getContentResolver(),
10174                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10175
10176        synchronized (this) {
10177            mAlwaysFinishActivities = enabled;
10178        }
10179    }
10180
10181    @Override
10182    public void setActivityController(IActivityController controller) {
10183        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10184                "setActivityController()");
10185        synchronized (this) {
10186            mController = controller;
10187            Watchdog.getInstance().setActivityController(controller);
10188        }
10189    }
10190
10191    @Override
10192    public void setUserIsMonkey(boolean userIsMonkey) {
10193        synchronized (this) {
10194            synchronized (mPidsSelfLocked) {
10195                final int callingPid = Binder.getCallingPid();
10196                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10197                if (precessRecord == null) {
10198                    throw new SecurityException("Unknown process: " + callingPid);
10199                }
10200                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10201                    throw new SecurityException("Only an instrumentation process "
10202                            + "with a UiAutomation can call setUserIsMonkey");
10203                }
10204            }
10205            mUserIsMonkey = userIsMonkey;
10206        }
10207    }
10208
10209    @Override
10210    public boolean isUserAMonkey() {
10211        synchronized (this) {
10212            // If there is a controller also implies the user is a monkey.
10213            return (mUserIsMonkey || mController != null);
10214        }
10215    }
10216
10217    public void requestBugReport() {
10218        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10219        SystemProperties.set("ctl.start", "bugreport");
10220    }
10221
10222    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10223        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10224    }
10225
10226    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10227        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10228            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10229        }
10230        return KEY_DISPATCHING_TIMEOUT;
10231    }
10232
10233    @Override
10234    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10235        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10236                != PackageManager.PERMISSION_GRANTED) {
10237            throw new SecurityException("Requires permission "
10238                    + android.Manifest.permission.FILTER_EVENTS);
10239        }
10240        ProcessRecord proc;
10241        long timeout;
10242        synchronized (this) {
10243            synchronized (mPidsSelfLocked) {
10244                proc = mPidsSelfLocked.get(pid);
10245            }
10246            timeout = getInputDispatchingTimeoutLocked(proc);
10247        }
10248
10249        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10250            return -1;
10251        }
10252
10253        return timeout;
10254    }
10255
10256    /**
10257     * Handle input dispatching timeouts.
10258     * Returns whether input dispatching should be aborted or not.
10259     */
10260    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10261            final ActivityRecord activity, final ActivityRecord parent,
10262            final boolean aboveSystem, String reason) {
10263        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10264                != PackageManager.PERMISSION_GRANTED) {
10265            throw new SecurityException("Requires permission "
10266                    + android.Manifest.permission.FILTER_EVENTS);
10267        }
10268
10269        final String annotation;
10270        if (reason == null) {
10271            annotation = "Input dispatching timed out";
10272        } else {
10273            annotation = "Input dispatching timed out (" + reason + ")";
10274        }
10275
10276        if (proc != null) {
10277            synchronized (this) {
10278                if (proc.debugging) {
10279                    return false;
10280                }
10281
10282                if (mDidDexOpt) {
10283                    // Give more time since we were dexopting.
10284                    mDidDexOpt = false;
10285                    return false;
10286                }
10287
10288                if (proc.instrumentationClass != null) {
10289                    Bundle info = new Bundle();
10290                    info.putString("shortMsg", "keyDispatchingTimedOut");
10291                    info.putString("longMsg", annotation);
10292                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10293                    return true;
10294                }
10295            }
10296            mHandler.post(new Runnable() {
10297                @Override
10298                public void run() {
10299                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10300                }
10301            });
10302        }
10303
10304        return true;
10305    }
10306
10307    public Bundle getAssistContextExtras(int requestType) {
10308        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10309                "getAssistContextExtras()");
10310        PendingAssistExtras pae;
10311        Bundle extras = new Bundle();
10312        synchronized (this) {
10313            ActivityRecord activity = getFocusedStack().mResumedActivity;
10314            if (activity == null) {
10315                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10316                return null;
10317            }
10318            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10319            if (activity.app == null || activity.app.thread == null) {
10320                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10321                return extras;
10322            }
10323            if (activity.app.pid == Binder.getCallingPid()) {
10324                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10325                return extras;
10326            }
10327            pae = new PendingAssistExtras(activity);
10328            try {
10329                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10330                        requestType);
10331                mPendingAssistExtras.add(pae);
10332                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10333            } catch (RemoteException e) {
10334                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10335                return extras;
10336            }
10337        }
10338        synchronized (pae) {
10339            while (!pae.haveResult) {
10340                try {
10341                    pae.wait();
10342                } catch (InterruptedException e) {
10343                }
10344            }
10345            if (pae.result != null) {
10346                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10347            }
10348        }
10349        synchronized (this) {
10350            mPendingAssistExtras.remove(pae);
10351            mHandler.removeCallbacks(pae);
10352        }
10353        return extras;
10354    }
10355
10356    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10357        PendingAssistExtras pae = (PendingAssistExtras)token;
10358        synchronized (pae) {
10359            pae.result = extras;
10360            pae.haveResult = true;
10361            pae.notifyAll();
10362        }
10363    }
10364
10365    public void registerProcessObserver(IProcessObserver observer) {
10366        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10367                "registerProcessObserver()");
10368        synchronized (this) {
10369            mProcessObservers.register(observer);
10370        }
10371    }
10372
10373    @Override
10374    public void unregisterProcessObserver(IProcessObserver observer) {
10375        synchronized (this) {
10376            mProcessObservers.unregister(observer);
10377        }
10378    }
10379
10380    @Override
10381    public boolean convertFromTranslucent(IBinder token) {
10382        final long origId = Binder.clearCallingIdentity();
10383        try {
10384            synchronized (this) {
10385                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10386                if (r == null) {
10387                    return false;
10388                }
10389                final boolean translucentChanged = r.changeWindowTranslucency(true);
10390                if (translucentChanged) {
10391                    r.task.stack.releaseBackgroundResources();
10392                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10393                }
10394                mWindowManager.setAppFullscreen(token, true);
10395                return translucentChanged;
10396            }
10397        } finally {
10398            Binder.restoreCallingIdentity(origId);
10399        }
10400    }
10401
10402    @Override
10403    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10404        final long origId = Binder.clearCallingIdentity();
10405        try {
10406            synchronized (this) {
10407                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10408                if (r == null) {
10409                    return false;
10410                }
10411                int index = r.task.mActivities.lastIndexOf(r);
10412                if (index > 0) {
10413                    ActivityRecord under = r.task.mActivities.get(index - 1);
10414                    under.returningOptions = options;
10415                }
10416                final boolean translucentChanged = r.changeWindowTranslucency(false);
10417                if (translucentChanged) {
10418                    r.task.stack.convertToTranslucent(r);
10419                }
10420                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10421                mWindowManager.setAppFullscreen(token, false);
10422                return translucentChanged;
10423            }
10424        } finally {
10425            Binder.restoreCallingIdentity(origId);
10426        }
10427    }
10428
10429    @Override
10430    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10431        final long origId = Binder.clearCallingIdentity();
10432        try {
10433            synchronized (this) {
10434                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10435                if (r != null) {
10436                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10437                }
10438            }
10439            return false;
10440        } finally {
10441            Binder.restoreCallingIdentity(origId);
10442        }
10443    }
10444
10445    @Override
10446    public boolean isBackgroundVisibleBehind(IBinder token) {
10447        final long origId = Binder.clearCallingIdentity();
10448        try {
10449            synchronized (this) {
10450                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10451                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10452                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10453                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10454                return visible;
10455            }
10456        } finally {
10457            Binder.restoreCallingIdentity(origId);
10458        }
10459    }
10460
10461    @Override
10462    public ActivityOptions getActivityOptions(IBinder token) {
10463        final long origId = Binder.clearCallingIdentity();
10464        try {
10465            synchronized (this) {
10466                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10467                if (r != null) {
10468                    final ActivityOptions activityOptions = r.pendingOptions;
10469                    r.pendingOptions = null;
10470                    return activityOptions;
10471                }
10472                return null;
10473            }
10474        } finally {
10475            Binder.restoreCallingIdentity(origId);
10476        }
10477    }
10478
10479    @Override
10480    public void setImmersive(IBinder token, boolean immersive) {
10481        synchronized(this) {
10482            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10483            if (r == null) {
10484                throw new IllegalArgumentException();
10485            }
10486            r.immersive = immersive;
10487
10488            // update associated state if we're frontmost
10489            if (r == mFocusedActivity) {
10490                if (DEBUG_IMMERSIVE) {
10491                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10492                }
10493                applyUpdateLockStateLocked(r);
10494            }
10495        }
10496    }
10497
10498    @Override
10499    public boolean isImmersive(IBinder token) {
10500        synchronized (this) {
10501            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10502            if (r == null) {
10503                throw new IllegalArgumentException();
10504            }
10505            return r.immersive;
10506        }
10507    }
10508
10509    public boolean isTopActivityImmersive() {
10510        enforceNotIsolatedCaller("startActivity");
10511        synchronized (this) {
10512            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10513            return (r != null) ? r.immersive : false;
10514        }
10515    }
10516
10517    @Override
10518    public boolean isTopOfTask(IBinder token) {
10519        synchronized (this) {
10520            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10521            if (r == null) {
10522                throw new IllegalArgumentException();
10523            }
10524            return r.task.getTopActivity() == r;
10525        }
10526    }
10527
10528    public final void enterSafeMode() {
10529        synchronized(this) {
10530            // It only makes sense to do this before the system is ready
10531            // and started launching other packages.
10532            if (!mSystemReady) {
10533                try {
10534                    AppGlobals.getPackageManager().enterSafeMode();
10535                } catch (RemoteException e) {
10536                }
10537            }
10538
10539            mSafeMode = true;
10540        }
10541    }
10542
10543    public final void showSafeModeOverlay() {
10544        View v = LayoutInflater.from(mContext).inflate(
10545                com.android.internal.R.layout.safe_mode, null);
10546        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10547        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10548        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10549        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10550        lp.gravity = Gravity.BOTTOM | Gravity.START;
10551        lp.format = v.getBackground().getOpacity();
10552        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10553                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10554        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10555        ((WindowManager)mContext.getSystemService(
10556                Context.WINDOW_SERVICE)).addView(v, lp);
10557    }
10558
10559    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10560        if (!(sender instanceof PendingIntentRecord)) {
10561            return;
10562        }
10563        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10564        synchronized (stats) {
10565            if (mBatteryStatsService.isOnBattery()) {
10566                mBatteryStatsService.enforceCallingPermission();
10567                PendingIntentRecord rec = (PendingIntentRecord)sender;
10568                int MY_UID = Binder.getCallingUid();
10569                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10570                BatteryStatsImpl.Uid.Pkg pkg =
10571                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10572                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10573                pkg.incWakeupsLocked();
10574            }
10575        }
10576    }
10577
10578    public boolean killPids(int[] pids, String pReason, boolean secure) {
10579        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10580            throw new SecurityException("killPids only available to the system");
10581        }
10582        String reason = (pReason == null) ? "Unknown" : pReason;
10583        // XXX Note: don't acquire main activity lock here, because the window
10584        // manager calls in with its locks held.
10585
10586        boolean killed = false;
10587        synchronized (mPidsSelfLocked) {
10588            int[] types = new int[pids.length];
10589            int worstType = 0;
10590            for (int i=0; i<pids.length; i++) {
10591                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10592                if (proc != null) {
10593                    int type = proc.setAdj;
10594                    types[i] = type;
10595                    if (type > worstType) {
10596                        worstType = type;
10597                    }
10598                }
10599            }
10600
10601            // If the worst oom_adj is somewhere in the cached proc LRU range,
10602            // then constrain it so we will kill all cached procs.
10603            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10604                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10605                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10606            }
10607
10608            // If this is not a secure call, don't let it kill processes that
10609            // are important.
10610            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10611                worstType = ProcessList.SERVICE_ADJ;
10612            }
10613
10614            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10615            for (int i=0; i<pids.length; i++) {
10616                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10617                if (proc == null) {
10618                    continue;
10619                }
10620                int adj = proc.setAdj;
10621                if (adj >= worstType && !proc.killedByAm) {
10622                    proc.kill(reason, true);
10623                    killed = true;
10624                }
10625            }
10626        }
10627        return killed;
10628    }
10629
10630    @Override
10631    public void killUid(int uid, String reason) {
10632        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10633            throw new SecurityException("killUid only available to the system");
10634        }
10635        synchronized (this) {
10636            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10637                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10638                    reason != null ? reason : "kill uid");
10639        }
10640    }
10641
10642    @Override
10643    public boolean killProcessesBelowForeground(String reason) {
10644        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10645            throw new SecurityException("killProcessesBelowForeground() only available to system");
10646        }
10647
10648        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10649    }
10650
10651    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10652        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10653            throw new SecurityException("killProcessesBelowAdj() only available to system");
10654        }
10655
10656        boolean killed = false;
10657        synchronized (mPidsSelfLocked) {
10658            final int size = mPidsSelfLocked.size();
10659            for (int i = 0; i < size; i++) {
10660                final int pid = mPidsSelfLocked.keyAt(i);
10661                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10662                if (proc == null) continue;
10663
10664                final int adj = proc.setAdj;
10665                if (adj > belowAdj && !proc.killedByAm) {
10666                    proc.kill(reason, true);
10667                    killed = true;
10668                }
10669            }
10670        }
10671        return killed;
10672    }
10673
10674    @Override
10675    public void hang(final IBinder who, boolean allowRestart) {
10676        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10677                != PackageManager.PERMISSION_GRANTED) {
10678            throw new SecurityException("Requires permission "
10679                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10680        }
10681
10682        final IBinder.DeathRecipient death = new DeathRecipient() {
10683            @Override
10684            public void binderDied() {
10685                synchronized (this) {
10686                    notifyAll();
10687                }
10688            }
10689        };
10690
10691        try {
10692            who.linkToDeath(death, 0);
10693        } catch (RemoteException e) {
10694            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10695            return;
10696        }
10697
10698        synchronized (this) {
10699            Watchdog.getInstance().setAllowRestart(allowRestart);
10700            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10701            synchronized (death) {
10702                while (who.isBinderAlive()) {
10703                    try {
10704                        death.wait();
10705                    } catch (InterruptedException e) {
10706                    }
10707                }
10708            }
10709            Watchdog.getInstance().setAllowRestart(true);
10710        }
10711    }
10712
10713    @Override
10714    public void restart() {
10715        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10716                != PackageManager.PERMISSION_GRANTED) {
10717            throw new SecurityException("Requires permission "
10718                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10719        }
10720
10721        Log.i(TAG, "Sending shutdown broadcast...");
10722
10723        BroadcastReceiver br = new BroadcastReceiver() {
10724            @Override public void onReceive(Context context, Intent intent) {
10725                // Now the broadcast is done, finish up the low-level shutdown.
10726                Log.i(TAG, "Shutting down activity manager...");
10727                shutdown(10000);
10728                Log.i(TAG, "Shutdown complete, restarting!");
10729                Process.killProcess(Process.myPid());
10730                System.exit(10);
10731            }
10732        };
10733
10734        // First send the high-level shut down broadcast.
10735        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10736        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10737        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10738        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10739        mContext.sendOrderedBroadcastAsUser(intent,
10740                UserHandle.ALL, null, br, mHandler, 0, null, null);
10741        */
10742        br.onReceive(mContext, intent);
10743    }
10744
10745    private long getLowRamTimeSinceIdle(long now) {
10746        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10747    }
10748
10749    @Override
10750    public void performIdleMaintenance() {
10751        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10752                != PackageManager.PERMISSION_GRANTED) {
10753            throw new SecurityException("Requires permission "
10754                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10755        }
10756
10757        synchronized (this) {
10758            final long now = SystemClock.uptimeMillis();
10759            final long timeSinceLastIdle = now - mLastIdleTime;
10760            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10761            mLastIdleTime = now;
10762            mLowRamTimeSinceLastIdle = 0;
10763            if (mLowRamStartTime != 0) {
10764                mLowRamStartTime = now;
10765            }
10766
10767            StringBuilder sb = new StringBuilder(128);
10768            sb.append("Idle maintenance over ");
10769            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10770            sb.append(" low RAM for ");
10771            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10772            Slog.i(TAG, sb.toString());
10773
10774            // If at least 1/3 of our time since the last idle period has been spent
10775            // with RAM low, then we want to kill processes.
10776            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10777
10778            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10779                ProcessRecord proc = mLruProcesses.get(i);
10780                if (proc.notCachedSinceIdle) {
10781                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10782                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10783                        if (doKilling && proc.initialIdlePss != 0
10784                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10785                            proc.kill("idle maint (pss " + proc.lastPss
10786                                    + " from " + proc.initialIdlePss + ")", true);
10787                        }
10788                    }
10789                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10790                    proc.notCachedSinceIdle = true;
10791                    proc.initialIdlePss = 0;
10792                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10793                            isSleeping(), now);
10794                }
10795            }
10796
10797            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10798            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10799        }
10800    }
10801
10802    private void retrieveSettings() {
10803        final ContentResolver resolver = mContext.getContentResolver();
10804        String debugApp = Settings.Global.getString(
10805            resolver, Settings.Global.DEBUG_APP);
10806        boolean waitForDebugger = Settings.Global.getInt(
10807            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10808        boolean alwaysFinishActivities = Settings.Global.getInt(
10809            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10810        boolean forceRtl = Settings.Global.getInt(
10811                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10812        // Transfer any global setting for forcing RTL layout, into a System Property
10813        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10814
10815        Configuration configuration = new Configuration();
10816        Settings.System.getConfiguration(resolver, configuration);
10817        if (forceRtl) {
10818            // This will take care of setting the correct layout direction flags
10819            configuration.setLayoutDirection(configuration.locale);
10820        }
10821
10822        synchronized (this) {
10823            mDebugApp = mOrigDebugApp = debugApp;
10824            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10825            mAlwaysFinishActivities = alwaysFinishActivities;
10826            // This happens before any activities are started, so we can
10827            // change mConfiguration in-place.
10828            updateConfigurationLocked(configuration, null, false, true);
10829            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10830        }
10831    }
10832
10833    /** Loads resources after the current configuration has been set. */
10834    private void loadResourcesOnSystemReady() {
10835        final Resources res = mContext.getResources();
10836        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10837        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10838        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10839    }
10840
10841    public boolean testIsSystemReady() {
10842        // no need to synchronize(this) just to read & return the value
10843        return mSystemReady;
10844    }
10845
10846    private static File getCalledPreBootReceiversFile() {
10847        File dataDir = Environment.getDataDirectory();
10848        File systemDir = new File(dataDir, "system");
10849        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10850        return fname;
10851    }
10852
10853    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10854        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10855        File file = getCalledPreBootReceiversFile();
10856        FileInputStream fis = null;
10857        try {
10858            fis = new FileInputStream(file);
10859            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10860            int fvers = dis.readInt();
10861            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10862                String vers = dis.readUTF();
10863                String codename = dis.readUTF();
10864                String build = dis.readUTF();
10865                if (android.os.Build.VERSION.RELEASE.equals(vers)
10866                        && android.os.Build.VERSION.CODENAME.equals(codename)
10867                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10868                    int num = dis.readInt();
10869                    while (num > 0) {
10870                        num--;
10871                        String pkg = dis.readUTF();
10872                        String cls = dis.readUTF();
10873                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10874                    }
10875                }
10876            }
10877        } catch (FileNotFoundException e) {
10878        } catch (IOException e) {
10879            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10880        } finally {
10881            if (fis != null) {
10882                try {
10883                    fis.close();
10884                } catch (IOException e) {
10885                }
10886            }
10887        }
10888        return lastDoneReceivers;
10889    }
10890
10891    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10892        File file = getCalledPreBootReceiversFile();
10893        FileOutputStream fos = null;
10894        DataOutputStream dos = null;
10895        try {
10896            fos = new FileOutputStream(file);
10897            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10898            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10899            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10900            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10901            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10902            dos.writeInt(list.size());
10903            for (int i=0; i<list.size(); i++) {
10904                dos.writeUTF(list.get(i).getPackageName());
10905                dos.writeUTF(list.get(i).getClassName());
10906            }
10907        } catch (IOException e) {
10908            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10909            file.delete();
10910        } finally {
10911            FileUtils.sync(fos);
10912            if (dos != null) {
10913                try {
10914                    dos.close();
10915                } catch (IOException e) {
10916                    // TODO Auto-generated catch block
10917                    e.printStackTrace();
10918                }
10919            }
10920        }
10921    }
10922
10923    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10924            ArrayList<ComponentName> doneReceivers, int userId) {
10925        boolean waitingUpdate = false;
10926        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10927        List<ResolveInfo> ris = null;
10928        try {
10929            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10930                    intent, null, 0, userId);
10931        } catch (RemoteException e) {
10932        }
10933        if (ris != null) {
10934            for (int i=ris.size()-1; i>=0; i--) {
10935                if ((ris.get(i).activityInfo.applicationInfo.flags
10936                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10937                    ris.remove(i);
10938                }
10939            }
10940            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10941
10942            // For User 0, load the version number. When delivering to a new user, deliver
10943            // to all receivers.
10944            if (userId == UserHandle.USER_OWNER) {
10945                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10946                for (int i=0; i<ris.size(); i++) {
10947                    ActivityInfo ai = ris.get(i).activityInfo;
10948                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10949                    if (lastDoneReceivers.contains(comp)) {
10950                        // We already did the pre boot receiver for this app with the current
10951                        // platform version, so don't do it again...
10952                        ris.remove(i);
10953                        i--;
10954                        // ...however, do keep it as one that has been done, so we don't
10955                        // forget about it when rewriting the file of last done receivers.
10956                        doneReceivers.add(comp);
10957                    }
10958                }
10959            }
10960
10961            // If primary user, send broadcast to all available users, else just to userId
10962            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10963                    : new int[] { userId };
10964            for (int i = 0; i < ris.size(); i++) {
10965                ActivityInfo ai = ris.get(i).activityInfo;
10966                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10967                doneReceivers.add(comp);
10968                intent.setComponent(comp);
10969                for (int j=0; j<users.length; j++) {
10970                    IIntentReceiver finisher = null;
10971                    // On last receiver and user, set up a completion callback
10972                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10973                        finisher = new IIntentReceiver.Stub() {
10974                            public void performReceive(Intent intent, int resultCode,
10975                                    String data, Bundle extras, boolean ordered,
10976                                    boolean sticky, int sendingUser) {
10977                                // The raw IIntentReceiver interface is called
10978                                // with the AM lock held, so redispatch to
10979                                // execute our code without the lock.
10980                                mHandler.post(onFinishCallback);
10981                            }
10982                        };
10983                    }
10984                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10985                            + " for user " + users[j]);
10986                    broadcastIntentLocked(null, null, intent, null, finisher,
10987                            0, null, null, null, AppOpsManager.OP_NONE,
10988                            true, false, MY_PID, Process.SYSTEM_UID,
10989                            users[j]);
10990                    if (finisher != null) {
10991                        waitingUpdate = true;
10992                    }
10993                }
10994            }
10995        }
10996
10997        return waitingUpdate;
10998    }
10999
11000    public void systemReady(final Runnable goingCallback) {
11001        synchronized(this) {
11002            if (mSystemReady) {
11003                // If we're done calling all the receivers, run the next "boot phase" passed in
11004                // by the SystemServer
11005                if (goingCallback != null) {
11006                    goingCallback.run();
11007                }
11008                return;
11009            }
11010
11011            // Make sure we have the current profile info, since it is needed for
11012            // security checks.
11013            updateCurrentProfileIdsLocked();
11014
11015            if (mRecentTasks == null) {
11016                mRecentTasks = mTaskPersister.restoreTasksLocked();
11017                if (!mRecentTasks.isEmpty()) {
11018                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11019                }
11020                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11021                mTaskPersister.startPersisting();
11022            }
11023
11024            // Check to see if there are any update receivers to run.
11025            if (!mDidUpdate) {
11026                if (mWaitingUpdate) {
11027                    return;
11028                }
11029                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11030                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11031                    public void run() {
11032                        synchronized (ActivityManagerService.this) {
11033                            mDidUpdate = true;
11034                        }
11035                        writeLastDonePreBootReceivers(doneReceivers);
11036                        showBootMessage(mContext.getText(
11037                                R.string.android_upgrading_complete),
11038                                false);
11039                        systemReady(goingCallback);
11040                    }
11041                }, doneReceivers, UserHandle.USER_OWNER);
11042
11043                if (mWaitingUpdate) {
11044                    return;
11045                }
11046                mDidUpdate = true;
11047            }
11048
11049            mAppOpsService.systemReady();
11050            mSystemReady = true;
11051        }
11052
11053        ArrayList<ProcessRecord> procsToKill = null;
11054        synchronized(mPidsSelfLocked) {
11055            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11056                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11057                if (!isAllowedWhileBooting(proc.info)){
11058                    if (procsToKill == null) {
11059                        procsToKill = new ArrayList<ProcessRecord>();
11060                    }
11061                    procsToKill.add(proc);
11062                }
11063            }
11064        }
11065
11066        synchronized(this) {
11067            if (procsToKill != null) {
11068                for (int i=procsToKill.size()-1; i>=0; i--) {
11069                    ProcessRecord proc = procsToKill.get(i);
11070                    Slog.i(TAG, "Removing system update proc: " + proc);
11071                    removeProcessLocked(proc, true, false, "system update done");
11072                }
11073            }
11074
11075            // Now that we have cleaned up any update processes, we
11076            // are ready to start launching real processes and know that
11077            // we won't trample on them any more.
11078            mProcessesReady = true;
11079        }
11080
11081        Slog.i(TAG, "System now ready");
11082        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11083            SystemClock.uptimeMillis());
11084
11085        synchronized(this) {
11086            // Make sure we have no pre-ready processes sitting around.
11087
11088            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11089                ResolveInfo ri = mContext.getPackageManager()
11090                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11091                                STOCK_PM_FLAGS);
11092                CharSequence errorMsg = null;
11093                if (ri != null) {
11094                    ActivityInfo ai = ri.activityInfo;
11095                    ApplicationInfo app = ai.applicationInfo;
11096                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11097                        mTopAction = Intent.ACTION_FACTORY_TEST;
11098                        mTopData = null;
11099                        mTopComponent = new ComponentName(app.packageName,
11100                                ai.name);
11101                    } else {
11102                        errorMsg = mContext.getResources().getText(
11103                                com.android.internal.R.string.factorytest_not_system);
11104                    }
11105                } else {
11106                    errorMsg = mContext.getResources().getText(
11107                            com.android.internal.R.string.factorytest_no_action);
11108                }
11109                if (errorMsg != null) {
11110                    mTopAction = null;
11111                    mTopData = null;
11112                    mTopComponent = null;
11113                    Message msg = Message.obtain();
11114                    msg.what = SHOW_FACTORY_ERROR_MSG;
11115                    msg.getData().putCharSequence("msg", errorMsg);
11116                    mHandler.sendMessage(msg);
11117                }
11118            }
11119        }
11120
11121        retrieveSettings();
11122        loadResourcesOnSystemReady();
11123
11124        synchronized (this) {
11125            readGrantedUriPermissionsLocked();
11126        }
11127
11128        if (goingCallback != null) goingCallback.run();
11129
11130        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11131                Integer.toString(mCurrentUserId), mCurrentUserId);
11132        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11133                Integer.toString(mCurrentUserId), mCurrentUserId);
11134        mSystemServiceManager.startUser(mCurrentUserId);
11135
11136        synchronized (this) {
11137            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11138                try {
11139                    List apps = AppGlobals.getPackageManager().
11140                        getPersistentApplications(STOCK_PM_FLAGS);
11141                    if (apps != null) {
11142                        int N = apps.size();
11143                        int i;
11144                        for (i=0; i<N; i++) {
11145                            ApplicationInfo info
11146                                = (ApplicationInfo)apps.get(i);
11147                            if (info != null &&
11148                                    !info.packageName.equals("android")) {
11149                                addAppLocked(info, false, null /* ABI override */);
11150                            }
11151                        }
11152                    }
11153                } catch (RemoteException ex) {
11154                    // pm is in same process, this will never happen.
11155                }
11156            }
11157
11158            // Start up initial activity.
11159            mBooting = true;
11160
11161            try {
11162                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11163                    Message msg = Message.obtain();
11164                    msg.what = SHOW_UID_ERROR_MSG;
11165                    mHandler.sendMessage(msg);
11166                }
11167            } catch (RemoteException e) {
11168            }
11169
11170            long ident = Binder.clearCallingIdentity();
11171            try {
11172                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11173                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11174                        | Intent.FLAG_RECEIVER_FOREGROUND);
11175                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11176                broadcastIntentLocked(null, null, intent,
11177                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11178                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11179                intent = new Intent(Intent.ACTION_USER_STARTING);
11180                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11181                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11182                broadcastIntentLocked(null, null, intent,
11183                        null, new IIntentReceiver.Stub() {
11184                            @Override
11185                            public void performReceive(Intent intent, int resultCode, String data,
11186                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11187                                    throws RemoteException {
11188                            }
11189                        }, 0, null, null,
11190                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11191                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11192            } catch (Throwable t) {
11193                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11194            } finally {
11195                Binder.restoreCallingIdentity(ident);
11196            }
11197            mStackSupervisor.resumeTopActivitiesLocked();
11198            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11199        }
11200    }
11201
11202    private boolean makeAppCrashingLocked(ProcessRecord app,
11203            String shortMsg, String longMsg, String stackTrace) {
11204        app.crashing = true;
11205        app.crashingReport = generateProcessError(app,
11206                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11207        startAppProblemLocked(app);
11208        app.stopFreezingAllLocked();
11209        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11210    }
11211
11212    private void makeAppNotRespondingLocked(ProcessRecord app,
11213            String activity, String shortMsg, String longMsg) {
11214        app.notResponding = true;
11215        app.notRespondingReport = generateProcessError(app,
11216                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11217                activity, shortMsg, longMsg, null);
11218        startAppProblemLocked(app);
11219        app.stopFreezingAllLocked();
11220    }
11221
11222    /**
11223     * Generate a process error record, suitable for attachment to a ProcessRecord.
11224     *
11225     * @param app The ProcessRecord in which the error occurred.
11226     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11227     *                      ActivityManager.AppErrorStateInfo
11228     * @param activity The activity associated with the crash, if known.
11229     * @param shortMsg Short message describing the crash.
11230     * @param longMsg Long message describing the crash.
11231     * @param stackTrace Full crash stack trace, may be null.
11232     *
11233     * @return Returns a fully-formed AppErrorStateInfo record.
11234     */
11235    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11236            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11237        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11238
11239        report.condition = condition;
11240        report.processName = app.processName;
11241        report.pid = app.pid;
11242        report.uid = app.info.uid;
11243        report.tag = activity;
11244        report.shortMsg = shortMsg;
11245        report.longMsg = longMsg;
11246        report.stackTrace = stackTrace;
11247
11248        return report;
11249    }
11250
11251    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11252        synchronized (this) {
11253            app.crashing = false;
11254            app.crashingReport = null;
11255            app.notResponding = false;
11256            app.notRespondingReport = null;
11257            if (app.anrDialog == fromDialog) {
11258                app.anrDialog = null;
11259            }
11260            if (app.waitDialog == fromDialog) {
11261                app.waitDialog = null;
11262            }
11263            if (app.pid > 0 && app.pid != MY_PID) {
11264                handleAppCrashLocked(app, null, null, null);
11265                app.kill("user request after error", true);
11266            }
11267        }
11268    }
11269
11270    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11271            String stackTrace) {
11272        long now = SystemClock.uptimeMillis();
11273
11274        Long crashTime;
11275        if (!app.isolated) {
11276            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11277        } else {
11278            crashTime = null;
11279        }
11280        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11281            // This process loses!
11282            Slog.w(TAG, "Process " + app.info.processName
11283                    + " has crashed too many times: killing!");
11284            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11285                    app.userId, app.info.processName, app.uid);
11286            mStackSupervisor.handleAppCrashLocked(app);
11287            if (!app.persistent) {
11288                // We don't want to start this process again until the user
11289                // explicitly does so...  but for persistent process, we really
11290                // need to keep it running.  If a persistent process is actually
11291                // repeatedly crashing, then badness for everyone.
11292                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11293                        app.info.processName);
11294                if (!app.isolated) {
11295                    // XXX We don't have a way to mark isolated processes
11296                    // as bad, since they don't have a peristent identity.
11297                    mBadProcesses.put(app.info.processName, app.uid,
11298                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11299                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11300                }
11301                app.bad = true;
11302                app.removed = true;
11303                // Don't let services in this process be restarted and potentially
11304                // annoy the user repeatedly.  Unless it is persistent, since those
11305                // processes run critical code.
11306                removeProcessLocked(app, false, false, "crash");
11307                mStackSupervisor.resumeTopActivitiesLocked();
11308                return false;
11309            }
11310            mStackSupervisor.resumeTopActivitiesLocked();
11311        } else {
11312            mStackSupervisor.finishTopRunningActivityLocked(app);
11313        }
11314
11315        // Bump up the crash count of any services currently running in the proc.
11316        for (int i=app.services.size()-1; i>=0; i--) {
11317            // Any services running in the application need to be placed
11318            // back in the pending list.
11319            ServiceRecord sr = app.services.valueAt(i);
11320            sr.crashCount++;
11321        }
11322
11323        // If the crashing process is what we consider to be the "home process" and it has been
11324        // replaced by a third-party app, clear the package preferred activities from packages
11325        // with a home activity running in the process to prevent a repeatedly crashing app
11326        // from blocking the user to manually clear the list.
11327        final ArrayList<ActivityRecord> activities = app.activities;
11328        if (app == mHomeProcess && activities.size() > 0
11329                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11330            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11331                final ActivityRecord r = activities.get(activityNdx);
11332                if (r.isHomeActivity()) {
11333                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11334                    try {
11335                        ActivityThread.getPackageManager()
11336                                .clearPackagePreferredActivities(r.packageName);
11337                    } catch (RemoteException c) {
11338                        // pm is in same process, this will never happen.
11339                    }
11340                }
11341            }
11342        }
11343
11344        if (!app.isolated) {
11345            // XXX Can't keep track of crash times for isolated processes,
11346            // because they don't have a perisistent identity.
11347            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11348        }
11349
11350        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11351        return true;
11352    }
11353
11354    void startAppProblemLocked(ProcessRecord app) {
11355        // If this app is not running under the current user, then we
11356        // can't give it a report button because that would require
11357        // launching the report UI under a different user.
11358        app.errorReportReceiver = null;
11359
11360        for (int userId : mCurrentProfileIds) {
11361            if (app.userId == userId) {
11362                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11363                        mContext, app.info.packageName, app.info.flags);
11364            }
11365        }
11366        skipCurrentReceiverLocked(app);
11367    }
11368
11369    void skipCurrentReceiverLocked(ProcessRecord app) {
11370        for (BroadcastQueue queue : mBroadcastQueues) {
11371            queue.skipCurrentReceiverLocked(app);
11372        }
11373    }
11374
11375    /**
11376     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11377     * The application process will exit immediately after this call returns.
11378     * @param app object of the crashing app, null for the system server
11379     * @param crashInfo describing the exception
11380     */
11381    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11382        ProcessRecord r = findAppProcess(app, "Crash");
11383        final String processName = app == null ? "system_server"
11384                : (r == null ? "unknown" : r.processName);
11385
11386        handleApplicationCrashInner("crash", r, processName, crashInfo);
11387    }
11388
11389    /* Native crash reporting uses this inner version because it needs to be somewhat
11390     * decoupled from the AM-managed cleanup lifecycle
11391     */
11392    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11393            ApplicationErrorReport.CrashInfo crashInfo) {
11394        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11395                UserHandle.getUserId(Binder.getCallingUid()), processName,
11396                r == null ? -1 : r.info.flags,
11397                crashInfo.exceptionClassName,
11398                crashInfo.exceptionMessage,
11399                crashInfo.throwFileName,
11400                crashInfo.throwLineNumber);
11401
11402        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11403
11404        crashApplication(r, crashInfo);
11405    }
11406
11407    public void handleApplicationStrictModeViolation(
11408            IBinder app,
11409            int violationMask,
11410            StrictMode.ViolationInfo info) {
11411        ProcessRecord r = findAppProcess(app, "StrictMode");
11412        if (r == null) {
11413            return;
11414        }
11415
11416        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11417            Integer stackFingerprint = info.hashCode();
11418            boolean logIt = true;
11419            synchronized (mAlreadyLoggedViolatedStacks) {
11420                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11421                    logIt = false;
11422                    // TODO: sub-sample into EventLog for these, with
11423                    // the info.durationMillis?  Then we'd get
11424                    // the relative pain numbers, without logging all
11425                    // the stack traces repeatedly.  We'd want to do
11426                    // likewise in the client code, which also does
11427                    // dup suppression, before the Binder call.
11428                } else {
11429                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11430                        mAlreadyLoggedViolatedStacks.clear();
11431                    }
11432                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11433                }
11434            }
11435            if (logIt) {
11436                logStrictModeViolationToDropBox(r, info);
11437            }
11438        }
11439
11440        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11441            AppErrorResult result = new AppErrorResult();
11442            synchronized (this) {
11443                final long origId = Binder.clearCallingIdentity();
11444
11445                Message msg = Message.obtain();
11446                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11447                HashMap<String, Object> data = new HashMap<String, Object>();
11448                data.put("result", result);
11449                data.put("app", r);
11450                data.put("violationMask", violationMask);
11451                data.put("info", info);
11452                msg.obj = data;
11453                mHandler.sendMessage(msg);
11454
11455                Binder.restoreCallingIdentity(origId);
11456            }
11457            int res = result.get();
11458            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11459        }
11460    }
11461
11462    // Depending on the policy in effect, there could be a bunch of
11463    // these in quick succession so we try to batch these together to
11464    // minimize disk writes, number of dropbox entries, and maximize
11465    // compression, by having more fewer, larger records.
11466    private void logStrictModeViolationToDropBox(
11467            ProcessRecord process,
11468            StrictMode.ViolationInfo info) {
11469        if (info == null) {
11470            return;
11471        }
11472        final boolean isSystemApp = process == null ||
11473                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11474                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11475        final String processName = process == null ? "unknown" : process.processName;
11476        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11477        final DropBoxManager dbox = (DropBoxManager)
11478                mContext.getSystemService(Context.DROPBOX_SERVICE);
11479
11480        // Exit early if the dropbox isn't configured to accept this report type.
11481        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11482
11483        boolean bufferWasEmpty;
11484        boolean needsFlush;
11485        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11486        synchronized (sb) {
11487            bufferWasEmpty = sb.length() == 0;
11488            appendDropBoxProcessHeaders(process, processName, sb);
11489            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11490            sb.append("System-App: ").append(isSystemApp).append("\n");
11491            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11492            if (info.violationNumThisLoop != 0) {
11493                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11494            }
11495            if (info.numAnimationsRunning != 0) {
11496                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11497            }
11498            if (info.broadcastIntentAction != null) {
11499                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11500            }
11501            if (info.durationMillis != -1) {
11502                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11503            }
11504            if (info.numInstances != -1) {
11505                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11506            }
11507            if (info.tags != null) {
11508                for (String tag : info.tags) {
11509                    sb.append("Span-Tag: ").append(tag).append("\n");
11510                }
11511            }
11512            sb.append("\n");
11513            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11514                sb.append(info.crashInfo.stackTrace);
11515            }
11516            sb.append("\n");
11517
11518            // Only buffer up to ~64k.  Various logging bits truncate
11519            // things at 128k.
11520            needsFlush = (sb.length() > 64 * 1024);
11521        }
11522
11523        // Flush immediately if the buffer's grown too large, or this
11524        // is a non-system app.  Non-system apps are isolated with a
11525        // different tag & policy and not batched.
11526        //
11527        // Batching is useful during internal testing with
11528        // StrictMode settings turned up high.  Without batching,
11529        // thousands of separate files could be created on boot.
11530        if (!isSystemApp || needsFlush) {
11531            new Thread("Error dump: " + dropboxTag) {
11532                @Override
11533                public void run() {
11534                    String report;
11535                    synchronized (sb) {
11536                        report = sb.toString();
11537                        sb.delete(0, sb.length());
11538                        sb.trimToSize();
11539                    }
11540                    if (report.length() != 0) {
11541                        dbox.addText(dropboxTag, report);
11542                    }
11543                }
11544            }.start();
11545            return;
11546        }
11547
11548        // System app batching:
11549        if (!bufferWasEmpty) {
11550            // An existing dropbox-writing thread is outstanding, so
11551            // we don't need to start it up.  The existing thread will
11552            // catch the buffer appends we just did.
11553            return;
11554        }
11555
11556        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11557        // (After this point, we shouldn't access AMS internal data structures.)
11558        new Thread("Error dump: " + dropboxTag) {
11559            @Override
11560            public void run() {
11561                // 5 second sleep to let stacks arrive and be batched together
11562                try {
11563                    Thread.sleep(5000);  // 5 seconds
11564                } catch (InterruptedException e) {}
11565
11566                String errorReport;
11567                synchronized (mStrictModeBuffer) {
11568                    errorReport = mStrictModeBuffer.toString();
11569                    if (errorReport.length() == 0) {
11570                        return;
11571                    }
11572                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11573                    mStrictModeBuffer.trimToSize();
11574                }
11575                dbox.addText(dropboxTag, errorReport);
11576            }
11577        }.start();
11578    }
11579
11580    /**
11581     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11582     * @param app object of the crashing app, null for the system server
11583     * @param tag reported by the caller
11584     * @param system whether this wtf is coming from the system
11585     * @param crashInfo describing the context of the error
11586     * @return true if the process should exit immediately (WTF is fatal)
11587     */
11588    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11589            final ApplicationErrorReport.CrashInfo crashInfo) {
11590        final ProcessRecord r = findAppProcess(app, "WTF");
11591        final String processName = app == null ? "system_server"
11592                : (r == null ? "unknown" : r.processName);
11593
11594        EventLog.writeEvent(EventLogTags.AM_WTF,
11595                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11596                processName,
11597                r == null ? -1 : r.info.flags,
11598                tag, crashInfo.exceptionMessage);
11599
11600        if (system) {
11601            // If this is coming from the system, we could very well have low-level
11602            // system locks held, so we want to do this all asynchronously.  And we
11603            // never want this to become fatal, so there is that too.
11604            mHandler.post(new Runnable() {
11605                @Override public void run() {
11606                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11607                            crashInfo);
11608                }
11609            });
11610            return false;
11611        }
11612
11613        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11614
11615        if (r != null && r.pid != Process.myPid() &&
11616                Settings.Global.getInt(mContext.getContentResolver(),
11617                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11618            crashApplication(r, crashInfo);
11619            return true;
11620        } else {
11621            return false;
11622        }
11623    }
11624
11625    /**
11626     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11627     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11628     */
11629    private ProcessRecord findAppProcess(IBinder app, String reason) {
11630        if (app == null) {
11631            return null;
11632        }
11633
11634        synchronized (this) {
11635            final int NP = mProcessNames.getMap().size();
11636            for (int ip=0; ip<NP; ip++) {
11637                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11638                final int NA = apps.size();
11639                for (int ia=0; ia<NA; ia++) {
11640                    ProcessRecord p = apps.valueAt(ia);
11641                    if (p.thread != null && p.thread.asBinder() == app) {
11642                        return p;
11643                    }
11644                }
11645            }
11646
11647            Slog.w(TAG, "Can't find mystery application for " + reason
11648                    + " from pid=" + Binder.getCallingPid()
11649                    + " uid=" + Binder.getCallingUid() + ": " + app);
11650            return null;
11651        }
11652    }
11653
11654    /**
11655     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11656     * to append various headers to the dropbox log text.
11657     */
11658    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11659            StringBuilder sb) {
11660        // Watchdog thread ends up invoking this function (with
11661        // a null ProcessRecord) to add the stack file to dropbox.
11662        // Do not acquire a lock on this (am) in such cases, as it
11663        // could cause a potential deadlock, if and when watchdog
11664        // is invoked due to unavailability of lock on am and it
11665        // would prevent watchdog from killing system_server.
11666        if (process == null) {
11667            sb.append("Process: ").append(processName).append("\n");
11668            return;
11669        }
11670        // Note: ProcessRecord 'process' is guarded by the service
11671        // instance.  (notably process.pkgList, which could otherwise change
11672        // concurrently during execution of this method)
11673        synchronized (this) {
11674            sb.append("Process: ").append(processName).append("\n");
11675            int flags = process.info.flags;
11676            IPackageManager pm = AppGlobals.getPackageManager();
11677            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11678            for (int ip=0; ip<process.pkgList.size(); ip++) {
11679                String pkg = process.pkgList.keyAt(ip);
11680                sb.append("Package: ").append(pkg);
11681                try {
11682                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11683                    if (pi != null) {
11684                        sb.append(" v").append(pi.versionCode);
11685                        if (pi.versionName != null) {
11686                            sb.append(" (").append(pi.versionName).append(")");
11687                        }
11688                    }
11689                } catch (RemoteException e) {
11690                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11691                }
11692                sb.append("\n");
11693            }
11694        }
11695    }
11696
11697    private static String processClass(ProcessRecord process) {
11698        if (process == null || process.pid == MY_PID) {
11699            return "system_server";
11700        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11701            return "system_app";
11702        } else {
11703            return "data_app";
11704        }
11705    }
11706
11707    /**
11708     * Write a description of an error (crash, WTF, ANR) to the drop box.
11709     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11710     * @param process which caused the error, null means the system server
11711     * @param activity which triggered the error, null if unknown
11712     * @param parent activity related to the error, null if unknown
11713     * @param subject line related to the error, null if absent
11714     * @param report in long form describing the error, null if absent
11715     * @param logFile to include in the report, null if none
11716     * @param crashInfo giving an application stack trace, null if absent
11717     */
11718    public void addErrorToDropBox(String eventType,
11719            ProcessRecord process, String processName, ActivityRecord activity,
11720            ActivityRecord parent, String subject,
11721            final String report, final File logFile,
11722            final ApplicationErrorReport.CrashInfo crashInfo) {
11723        // NOTE -- this must never acquire the ActivityManagerService lock,
11724        // otherwise the watchdog may be prevented from resetting the system.
11725
11726        final String dropboxTag = processClass(process) + "_" + eventType;
11727        final DropBoxManager dbox = (DropBoxManager)
11728                mContext.getSystemService(Context.DROPBOX_SERVICE);
11729
11730        // Exit early if the dropbox isn't configured to accept this report type.
11731        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11732
11733        final StringBuilder sb = new StringBuilder(1024);
11734        appendDropBoxProcessHeaders(process, processName, sb);
11735        if (activity != null) {
11736            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11737        }
11738        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11739            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11740        }
11741        if (parent != null && parent != activity) {
11742            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11743        }
11744        if (subject != null) {
11745            sb.append("Subject: ").append(subject).append("\n");
11746        }
11747        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11748        if (Debug.isDebuggerConnected()) {
11749            sb.append("Debugger: Connected\n");
11750        }
11751        sb.append("\n");
11752
11753        // Do the rest in a worker thread to avoid blocking the caller on I/O
11754        // (After this point, we shouldn't access AMS internal data structures.)
11755        Thread worker = new Thread("Error dump: " + dropboxTag) {
11756            @Override
11757            public void run() {
11758                if (report != null) {
11759                    sb.append(report);
11760                }
11761                if (logFile != null) {
11762                    try {
11763                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11764                                    "\n\n[[TRUNCATED]]"));
11765                    } catch (IOException e) {
11766                        Slog.e(TAG, "Error reading " + logFile, e);
11767                    }
11768                }
11769                if (crashInfo != null && crashInfo.stackTrace != null) {
11770                    sb.append(crashInfo.stackTrace);
11771                }
11772
11773                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11774                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11775                if (lines > 0) {
11776                    sb.append("\n");
11777
11778                    // Merge several logcat streams, and take the last N lines
11779                    InputStreamReader input = null;
11780                    try {
11781                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11782                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11783                                "-b", "crash",
11784                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11785
11786                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11787                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11788                        input = new InputStreamReader(logcat.getInputStream());
11789
11790                        int num;
11791                        char[] buf = new char[8192];
11792                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11793                    } catch (IOException e) {
11794                        Slog.e(TAG, "Error running logcat", e);
11795                    } finally {
11796                        if (input != null) try { input.close(); } catch (IOException e) {}
11797                    }
11798                }
11799
11800                dbox.addText(dropboxTag, sb.toString());
11801            }
11802        };
11803
11804        if (process == null) {
11805            // If process is null, we are being called from some internal code
11806            // and may be about to die -- run this synchronously.
11807            worker.run();
11808        } else {
11809            worker.start();
11810        }
11811    }
11812
11813    /**
11814     * Bring up the "unexpected error" dialog box for a crashing app.
11815     * Deal with edge cases (intercepts from instrumented applications,
11816     * ActivityController, error intent receivers, that sort of thing).
11817     * @param r the application crashing
11818     * @param crashInfo describing the failure
11819     */
11820    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11821        long timeMillis = System.currentTimeMillis();
11822        String shortMsg = crashInfo.exceptionClassName;
11823        String longMsg = crashInfo.exceptionMessage;
11824        String stackTrace = crashInfo.stackTrace;
11825        if (shortMsg != null && longMsg != null) {
11826            longMsg = shortMsg + ": " + longMsg;
11827        } else if (shortMsg != null) {
11828            longMsg = shortMsg;
11829        }
11830
11831        AppErrorResult result = new AppErrorResult();
11832        synchronized (this) {
11833            if (mController != null) {
11834                try {
11835                    String name = r != null ? r.processName : null;
11836                    int pid = r != null ? r.pid : Binder.getCallingPid();
11837                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11838                    if (!mController.appCrashed(name, pid,
11839                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11840                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11841                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11842                            Slog.w(TAG, "Skip killing native crashed app " + name
11843                                    + "(" + pid + ") during testing");
11844                        } else {
11845                            Slog.w(TAG, "Force-killing crashed app " + name
11846                                    + " at watcher's request");
11847                            if (r != null) {
11848                                r.kill("crash", true);
11849                            } else {
11850                                // Huh.
11851                                Process.killProcess(pid);
11852                                Process.killProcessGroup(uid, pid);
11853                            }
11854                        }
11855                        return;
11856                    }
11857                } catch (RemoteException e) {
11858                    mController = null;
11859                    Watchdog.getInstance().setActivityController(null);
11860                }
11861            }
11862
11863            final long origId = Binder.clearCallingIdentity();
11864
11865            // If this process is running instrumentation, finish it.
11866            if (r != null && r.instrumentationClass != null) {
11867                Slog.w(TAG, "Error in app " + r.processName
11868                      + " running instrumentation " + r.instrumentationClass + ":");
11869                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11870                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11871                Bundle info = new Bundle();
11872                info.putString("shortMsg", shortMsg);
11873                info.putString("longMsg", longMsg);
11874                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11875                Binder.restoreCallingIdentity(origId);
11876                return;
11877            }
11878
11879            // If we can't identify the process or it's already exceeded its crash quota,
11880            // quit right away without showing a crash dialog.
11881            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11882                Binder.restoreCallingIdentity(origId);
11883                return;
11884            }
11885
11886            Message msg = Message.obtain();
11887            msg.what = SHOW_ERROR_MSG;
11888            HashMap data = new HashMap();
11889            data.put("result", result);
11890            data.put("app", r);
11891            msg.obj = data;
11892            mHandler.sendMessage(msg);
11893
11894            Binder.restoreCallingIdentity(origId);
11895        }
11896
11897        int res = result.get();
11898
11899        Intent appErrorIntent = null;
11900        synchronized (this) {
11901            if (r != null && !r.isolated) {
11902                // XXX Can't keep track of crash time for isolated processes,
11903                // since they don't have a persistent identity.
11904                mProcessCrashTimes.put(r.info.processName, r.uid,
11905                        SystemClock.uptimeMillis());
11906            }
11907            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11908                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11909            }
11910        }
11911
11912        if (appErrorIntent != null) {
11913            try {
11914                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11915            } catch (ActivityNotFoundException e) {
11916                Slog.w(TAG, "bug report receiver dissappeared", e);
11917            }
11918        }
11919    }
11920
11921    Intent createAppErrorIntentLocked(ProcessRecord r,
11922            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11923        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11924        if (report == null) {
11925            return null;
11926        }
11927        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11928        result.setComponent(r.errorReportReceiver);
11929        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11930        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11931        return result;
11932    }
11933
11934    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11935            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11936        if (r.errorReportReceiver == null) {
11937            return null;
11938        }
11939
11940        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11941            return null;
11942        }
11943
11944        ApplicationErrorReport report = new ApplicationErrorReport();
11945        report.packageName = r.info.packageName;
11946        report.installerPackageName = r.errorReportReceiver.getPackageName();
11947        report.processName = r.processName;
11948        report.time = timeMillis;
11949        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11950
11951        if (r.crashing || r.forceCrashReport) {
11952            report.type = ApplicationErrorReport.TYPE_CRASH;
11953            report.crashInfo = crashInfo;
11954        } else if (r.notResponding) {
11955            report.type = ApplicationErrorReport.TYPE_ANR;
11956            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11957
11958            report.anrInfo.activity = r.notRespondingReport.tag;
11959            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11960            report.anrInfo.info = r.notRespondingReport.longMsg;
11961        }
11962
11963        return report;
11964    }
11965
11966    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11967        enforceNotIsolatedCaller("getProcessesInErrorState");
11968        // assume our apps are happy - lazy create the list
11969        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11970
11971        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11972                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11973        int userId = UserHandle.getUserId(Binder.getCallingUid());
11974
11975        synchronized (this) {
11976
11977            // iterate across all processes
11978            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11979                ProcessRecord app = mLruProcesses.get(i);
11980                if (!allUsers && app.userId != userId) {
11981                    continue;
11982                }
11983                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11984                    // This one's in trouble, so we'll generate a report for it
11985                    // crashes are higher priority (in case there's a crash *and* an anr)
11986                    ActivityManager.ProcessErrorStateInfo report = null;
11987                    if (app.crashing) {
11988                        report = app.crashingReport;
11989                    } else if (app.notResponding) {
11990                        report = app.notRespondingReport;
11991                    }
11992
11993                    if (report != null) {
11994                        if (errList == null) {
11995                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11996                        }
11997                        errList.add(report);
11998                    } else {
11999                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12000                                " crashing = " + app.crashing +
12001                                " notResponding = " + app.notResponding);
12002                    }
12003                }
12004            }
12005        }
12006
12007        return errList;
12008    }
12009
12010    static int procStateToImportance(int procState, int memAdj,
12011            ActivityManager.RunningAppProcessInfo currApp) {
12012        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12013        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12014            currApp.lru = memAdj;
12015        } else {
12016            currApp.lru = 0;
12017        }
12018        return imp;
12019    }
12020
12021    private void fillInProcMemInfo(ProcessRecord app,
12022            ActivityManager.RunningAppProcessInfo outInfo) {
12023        outInfo.pid = app.pid;
12024        outInfo.uid = app.info.uid;
12025        if (mHeavyWeightProcess == app) {
12026            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12027        }
12028        if (app.persistent) {
12029            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12030        }
12031        if (app.activities.size() > 0) {
12032            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12033        }
12034        outInfo.lastTrimLevel = app.trimMemoryLevel;
12035        int adj = app.curAdj;
12036        int procState = app.curProcState;
12037        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12038        outInfo.importanceReasonCode = app.adjTypeCode;
12039        outInfo.processState = app.curProcState;
12040    }
12041
12042    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12043        enforceNotIsolatedCaller("getRunningAppProcesses");
12044        // Lazy instantiation of list
12045        List<ActivityManager.RunningAppProcessInfo> runList = null;
12046        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12047                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12048        int userId = UserHandle.getUserId(Binder.getCallingUid());
12049        synchronized (this) {
12050            // Iterate across all processes
12051            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12052                ProcessRecord app = mLruProcesses.get(i);
12053                if (!allUsers && app.userId != userId) {
12054                    continue;
12055                }
12056                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12057                    // Generate process state info for running application
12058                    ActivityManager.RunningAppProcessInfo currApp =
12059                        new ActivityManager.RunningAppProcessInfo(app.processName,
12060                                app.pid, app.getPackageList());
12061                    fillInProcMemInfo(app, currApp);
12062                    if (app.adjSource instanceof ProcessRecord) {
12063                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12064                        currApp.importanceReasonImportance =
12065                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12066                                        app.adjSourceProcState);
12067                    } else if (app.adjSource instanceof ActivityRecord) {
12068                        ActivityRecord r = (ActivityRecord)app.adjSource;
12069                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12070                    }
12071                    if (app.adjTarget instanceof ComponentName) {
12072                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12073                    }
12074                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12075                    //        + " lru=" + currApp.lru);
12076                    if (runList == null) {
12077                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12078                    }
12079                    runList.add(currApp);
12080                }
12081            }
12082        }
12083        return runList;
12084    }
12085
12086    public List<ApplicationInfo> getRunningExternalApplications() {
12087        enforceNotIsolatedCaller("getRunningExternalApplications");
12088        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12089        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12090        if (runningApps != null && runningApps.size() > 0) {
12091            Set<String> extList = new HashSet<String>();
12092            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12093                if (app.pkgList != null) {
12094                    for (String pkg : app.pkgList) {
12095                        extList.add(pkg);
12096                    }
12097                }
12098            }
12099            IPackageManager pm = AppGlobals.getPackageManager();
12100            for (String pkg : extList) {
12101                try {
12102                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12103                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12104                        retList.add(info);
12105                    }
12106                } catch (RemoteException e) {
12107                }
12108            }
12109        }
12110        return retList;
12111    }
12112
12113    @Override
12114    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12115        enforceNotIsolatedCaller("getMyMemoryState");
12116        synchronized (this) {
12117            ProcessRecord proc;
12118            synchronized (mPidsSelfLocked) {
12119                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12120            }
12121            fillInProcMemInfo(proc, outInfo);
12122        }
12123    }
12124
12125    @Override
12126    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12127        if (checkCallingPermission(android.Manifest.permission.DUMP)
12128                != PackageManager.PERMISSION_GRANTED) {
12129            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12130                    + Binder.getCallingPid()
12131                    + ", uid=" + Binder.getCallingUid()
12132                    + " without permission "
12133                    + android.Manifest.permission.DUMP);
12134            return;
12135        }
12136
12137        boolean dumpAll = false;
12138        boolean dumpClient = false;
12139        String dumpPackage = null;
12140
12141        int opti = 0;
12142        while (opti < args.length) {
12143            String opt = args[opti];
12144            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12145                break;
12146            }
12147            opti++;
12148            if ("-a".equals(opt)) {
12149                dumpAll = true;
12150            } else if ("-c".equals(opt)) {
12151                dumpClient = true;
12152            } else if ("-h".equals(opt)) {
12153                pw.println("Activity manager dump options:");
12154                pw.println("  [-a] [-c] [-h] [cmd] ...");
12155                pw.println("  cmd may be one of:");
12156                pw.println("    a[ctivities]: activity stack state");
12157                pw.println("    r[recents]: recent activities state");
12158                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12159                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12160                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12161                pw.println("    o[om]: out of memory management");
12162                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12163                pw.println("    provider [COMP_SPEC]: provider client-side state");
12164                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12165                pw.println("    service [COMP_SPEC]: service client-side state");
12166                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12167                pw.println("    all: dump all activities");
12168                pw.println("    top: dump the top activity");
12169                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12170                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12171                pw.println("    a partial substring in a component name, a");
12172                pw.println("    hex object identifier.");
12173                pw.println("  -a: include all available server state.");
12174                pw.println("  -c: include client state.");
12175                return;
12176            } else {
12177                pw.println("Unknown argument: " + opt + "; use -h for help");
12178            }
12179        }
12180
12181        long origId = Binder.clearCallingIdentity();
12182        boolean more = false;
12183        // Is the caller requesting to dump a particular piece of data?
12184        if (opti < args.length) {
12185            String cmd = args[opti];
12186            opti++;
12187            if ("activities".equals(cmd) || "a".equals(cmd)) {
12188                synchronized (this) {
12189                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12190                }
12191            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12192                synchronized (this) {
12193                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12194                }
12195            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12196                String[] newArgs;
12197                String name;
12198                if (opti >= args.length) {
12199                    name = null;
12200                    newArgs = EMPTY_STRING_ARRAY;
12201                } else {
12202                    name = args[opti];
12203                    opti++;
12204                    newArgs = new String[args.length - opti];
12205                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12206                            args.length - opti);
12207                }
12208                synchronized (this) {
12209                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12210                }
12211            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12212                String[] newArgs;
12213                String name;
12214                if (opti >= args.length) {
12215                    name = null;
12216                    newArgs = EMPTY_STRING_ARRAY;
12217                } else {
12218                    name = args[opti];
12219                    opti++;
12220                    newArgs = new String[args.length - opti];
12221                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12222                            args.length - opti);
12223                }
12224                synchronized (this) {
12225                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12226                }
12227            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12228                String[] newArgs;
12229                String name;
12230                if (opti >= args.length) {
12231                    name = null;
12232                    newArgs = EMPTY_STRING_ARRAY;
12233                } else {
12234                    name = args[opti];
12235                    opti++;
12236                    newArgs = new String[args.length - opti];
12237                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12238                            args.length - opti);
12239                }
12240                synchronized (this) {
12241                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12242                }
12243            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12244                synchronized (this) {
12245                    dumpOomLocked(fd, pw, args, opti, true);
12246                }
12247            } else if ("provider".equals(cmd)) {
12248                String[] newArgs;
12249                String name;
12250                if (opti >= args.length) {
12251                    name = null;
12252                    newArgs = EMPTY_STRING_ARRAY;
12253                } else {
12254                    name = args[opti];
12255                    opti++;
12256                    newArgs = new String[args.length - opti];
12257                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12258                }
12259                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12260                    pw.println("No providers match: " + name);
12261                    pw.println("Use -h for help.");
12262                }
12263            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12264                synchronized (this) {
12265                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12266                }
12267            } else if ("service".equals(cmd)) {
12268                String[] newArgs;
12269                String name;
12270                if (opti >= args.length) {
12271                    name = null;
12272                    newArgs = EMPTY_STRING_ARRAY;
12273                } else {
12274                    name = args[opti];
12275                    opti++;
12276                    newArgs = new String[args.length - opti];
12277                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12278                            args.length - opti);
12279                }
12280                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12281                    pw.println("No services match: " + name);
12282                    pw.println("Use -h for help.");
12283                }
12284            } else if ("package".equals(cmd)) {
12285                String[] newArgs;
12286                if (opti >= args.length) {
12287                    pw.println("package: no package name specified");
12288                    pw.println("Use -h for help.");
12289                } else {
12290                    dumpPackage = args[opti];
12291                    opti++;
12292                    newArgs = new String[args.length - opti];
12293                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12294                            args.length - opti);
12295                    args = newArgs;
12296                    opti = 0;
12297                    more = true;
12298                }
12299            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12300                synchronized (this) {
12301                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12302                }
12303            } else {
12304                // Dumping a single activity?
12305                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12306                    pw.println("Bad activity command, or no activities match: " + cmd);
12307                    pw.println("Use -h for help.");
12308                }
12309            }
12310            if (!more) {
12311                Binder.restoreCallingIdentity(origId);
12312                return;
12313            }
12314        }
12315
12316        // No piece of data specified, dump everything.
12317        synchronized (this) {
12318            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12319            pw.println();
12320            if (dumpAll) {
12321                pw.println("-------------------------------------------------------------------------------");
12322            }
12323            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12324            pw.println();
12325            if (dumpAll) {
12326                pw.println("-------------------------------------------------------------------------------");
12327            }
12328            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12329            pw.println();
12330            if (dumpAll) {
12331                pw.println("-------------------------------------------------------------------------------");
12332            }
12333            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12334            pw.println();
12335            if (dumpAll) {
12336                pw.println("-------------------------------------------------------------------------------");
12337            }
12338            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12339            pw.println();
12340            if (dumpAll) {
12341                pw.println("-------------------------------------------------------------------------------");
12342            }
12343            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12344            pw.println();
12345            if (dumpAll) {
12346                pw.println("-------------------------------------------------------------------------------");
12347            }
12348            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12349        }
12350        Binder.restoreCallingIdentity(origId);
12351    }
12352
12353    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12354            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12355        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12356
12357        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12358                dumpPackage);
12359        boolean needSep = printedAnything;
12360
12361        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12362                dumpPackage, needSep, "  mFocusedActivity: ");
12363        if (printed) {
12364            printedAnything = true;
12365            needSep = false;
12366        }
12367
12368        if (dumpPackage == null) {
12369            if (needSep) {
12370                pw.println();
12371            }
12372            needSep = true;
12373            printedAnything = true;
12374            mStackSupervisor.dump(pw, "  ");
12375        }
12376
12377        if (!printedAnything) {
12378            pw.println("  (nothing)");
12379        }
12380    }
12381
12382    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12383            int opti, boolean dumpAll, String dumpPackage) {
12384        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12385
12386        boolean printedAnything = false;
12387
12388        if (mRecentTasks.size() > 0) {
12389            boolean printedHeader = false;
12390
12391            final int N = mRecentTasks.size();
12392            for (int i=0; i<N; i++) {
12393                TaskRecord tr = mRecentTasks.get(i);
12394                if (dumpPackage != null) {
12395                    if (tr.realActivity == null ||
12396                            !dumpPackage.equals(tr.realActivity)) {
12397                        continue;
12398                    }
12399                }
12400                if (!printedHeader) {
12401                    pw.println("  Recent tasks:");
12402                    printedHeader = true;
12403                    printedAnything = true;
12404                }
12405                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12406                        pw.println(tr);
12407                if (dumpAll) {
12408                    mRecentTasks.get(i).dump(pw, "    ");
12409                }
12410            }
12411        }
12412
12413        if (!printedAnything) {
12414            pw.println("  (nothing)");
12415        }
12416    }
12417
12418    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12419            int opti, boolean dumpAll, String dumpPackage) {
12420        boolean needSep = false;
12421        boolean printedAnything = false;
12422        int numPers = 0;
12423
12424        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12425
12426        if (dumpAll) {
12427            final int NP = mProcessNames.getMap().size();
12428            for (int ip=0; ip<NP; ip++) {
12429                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12430                final int NA = procs.size();
12431                for (int ia=0; ia<NA; ia++) {
12432                    ProcessRecord r = procs.valueAt(ia);
12433                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12434                        continue;
12435                    }
12436                    if (!needSep) {
12437                        pw.println("  All known processes:");
12438                        needSep = true;
12439                        printedAnything = true;
12440                    }
12441                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12442                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12443                        pw.print(" "); pw.println(r);
12444                    r.dump(pw, "    ");
12445                    if (r.persistent) {
12446                        numPers++;
12447                    }
12448                }
12449            }
12450        }
12451
12452        if (mIsolatedProcesses.size() > 0) {
12453            boolean printed = false;
12454            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12455                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12456                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12457                    continue;
12458                }
12459                if (!printed) {
12460                    if (needSep) {
12461                        pw.println();
12462                    }
12463                    pw.println("  Isolated process list (sorted by uid):");
12464                    printedAnything = true;
12465                    printed = true;
12466                    needSep = true;
12467                }
12468                pw.println(String.format("%sIsolated #%2d: %s",
12469                        "    ", i, r.toString()));
12470            }
12471        }
12472
12473        if (mLruProcesses.size() > 0) {
12474            if (needSep) {
12475                pw.println();
12476            }
12477            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12478                    pw.print(" total, non-act at ");
12479                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12480                    pw.print(", non-svc at ");
12481                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12482                    pw.println("):");
12483            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12484            needSep = true;
12485            printedAnything = true;
12486        }
12487
12488        if (dumpAll || dumpPackage != null) {
12489            synchronized (mPidsSelfLocked) {
12490                boolean printed = false;
12491                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12492                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12493                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12494                        continue;
12495                    }
12496                    if (!printed) {
12497                        if (needSep) pw.println();
12498                        needSep = true;
12499                        pw.println("  PID mappings:");
12500                        printed = true;
12501                        printedAnything = true;
12502                    }
12503                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12504                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12505                }
12506            }
12507        }
12508
12509        if (mForegroundProcesses.size() > 0) {
12510            synchronized (mPidsSelfLocked) {
12511                boolean printed = false;
12512                for (int i=0; i<mForegroundProcesses.size(); i++) {
12513                    ProcessRecord r = mPidsSelfLocked.get(
12514                            mForegroundProcesses.valueAt(i).pid);
12515                    if (dumpPackage != null && (r == null
12516                            || !r.pkgList.containsKey(dumpPackage))) {
12517                        continue;
12518                    }
12519                    if (!printed) {
12520                        if (needSep) pw.println();
12521                        needSep = true;
12522                        pw.println("  Foreground Processes:");
12523                        printed = true;
12524                        printedAnything = true;
12525                    }
12526                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12527                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12528                }
12529            }
12530        }
12531
12532        if (mPersistentStartingProcesses.size() > 0) {
12533            if (needSep) pw.println();
12534            needSep = true;
12535            printedAnything = true;
12536            pw.println("  Persisent processes that are starting:");
12537            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12538                    "Starting Norm", "Restarting PERS", dumpPackage);
12539        }
12540
12541        if (mRemovedProcesses.size() > 0) {
12542            if (needSep) pw.println();
12543            needSep = true;
12544            printedAnything = true;
12545            pw.println("  Processes that are being removed:");
12546            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12547                    "Removed Norm", "Removed PERS", dumpPackage);
12548        }
12549
12550        if (mProcessesOnHold.size() > 0) {
12551            if (needSep) pw.println();
12552            needSep = true;
12553            printedAnything = true;
12554            pw.println("  Processes that are on old until the system is ready:");
12555            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12556                    "OnHold Norm", "OnHold PERS", dumpPackage);
12557        }
12558
12559        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12560
12561        if (mProcessCrashTimes.getMap().size() > 0) {
12562            boolean printed = false;
12563            long now = SystemClock.uptimeMillis();
12564            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12565            final int NP = pmap.size();
12566            for (int ip=0; ip<NP; ip++) {
12567                String pname = pmap.keyAt(ip);
12568                SparseArray<Long> uids = pmap.valueAt(ip);
12569                final int N = uids.size();
12570                for (int i=0; i<N; i++) {
12571                    int puid = uids.keyAt(i);
12572                    ProcessRecord r = mProcessNames.get(pname, puid);
12573                    if (dumpPackage != null && (r == null
12574                            || !r.pkgList.containsKey(dumpPackage))) {
12575                        continue;
12576                    }
12577                    if (!printed) {
12578                        if (needSep) pw.println();
12579                        needSep = true;
12580                        pw.println("  Time since processes crashed:");
12581                        printed = true;
12582                        printedAnything = true;
12583                    }
12584                    pw.print("    Process "); pw.print(pname);
12585                            pw.print(" uid "); pw.print(puid);
12586                            pw.print(": last crashed ");
12587                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12588                            pw.println(" ago");
12589                }
12590            }
12591        }
12592
12593        if (mBadProcesses.getMap().size() > 0) {
12594            boolean printed = false;
12595            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12596            final int NP = pmap.size();
12597            for (int ip=0; ip<NP; ip++) {
12598                String pname = pmap.keyAt(ip);
12599                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12600                final int N = uids.size();
12601                for (int i=0; i<N; i++) {
12602                    int puid = uids.keyAt(i);
12603                    ProcessRecord r = mProcessNames.get(pname, puid);
12604                    if (dumpPackage != null && (r == null
12605                            || !r.pkgList.containsKey(dumpPackage))) {
12606                        continue;
12607                    }
12608                    if (!printed) {
12609                        if (needSep) pw.println();
12610                        needSep = true;
12611                        pw.println("  Bad processes:");
12612                        printedAnything = true;
12613                    }
12614                    BadProcessInfo info = uids.valueAt(i);
12615                    pw.print("    Bad process "); pw.print(pname);
12616                            pw.print(" uid "); pw.print(puid);
12617                            pw.print(": crashed at time "); pw.println(info.time);
12618                    if (info.shortMsg != null) {
12619                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12620                    }
12621                    if (info.longMsg != null) {
12622                        pw.print("      Long msg: "); pw.println(info.longMsg);
12623                    }
12624                    if (info.stack != null) {
12625                        pw.println("      Stack:");
12626                        int lastPos = 0;
12627                        for (int pos=0; pos<info.stack.length(); pos++) {
12628                            if (info.stack.charAt(pos) == '\n') {
12629                                pw.print("        ");
12630                                pw.write(info.stack, lastPos, pos-lastPos);
12631                                pw.println();
12632                                lastPos = pos+1;
12633                            }
12634                        }
12635                        if (lastPos < info.stack.length()) {
12636                            pw.print("        ");
12637                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12638                            pw.println();
12639                        }
12640                    }
12641                }
12642            }
12643        }
12644
12645        if (dumpPackage == null) {
12646            pw.println();
12647            needSep = false;
12648            pw.println("  mStartedUsers:");
12649            for (int i=0; i<mStartedUsers.size(); i++) {
12650                UserStartedState uss = mStartedUsers.valueAt(i);
12651                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12652                        pw.print(": "); uss.dump("", pw);
12653            }
12654            pw.print("  mStartedUserArray: [");
12655            for (int i=0; i<mStartedUserArray.length; i++) {
12656                if (i > 0) pw.print(", ");
12657                pw.print(mStartedUserArray[i]);
12658            }
12659            pw.println("]");
12660            pw.print("  mUserLru: [");
12661            for (int i=0; i<mUserLru.size(); i++) {
12662                if (i > 0) pw.print(", ");
12663                pw.print(mUserLru.get(i));
12664            }
12665            pw.println("]");
12666            if (dumpAll) {
12667                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12668            }
12669            synchronized (mUserProfileGroupIdsSelfLocked) {
12670                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12671                    pw.println("  mUserProfileGroupIds:");
12672                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12673                        pw.print("    User #");
12674                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12675                        pw.print(" -> profile #");
12676                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12677                    }
12678                }
12679            }
12680        }
12681        if (mHomeProcess != null && (dumpPackage == null
12682                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12683            if (needSep) {
12684                pw.println();
12685                needSep = false;
12686            }
12687            pw.println("  mHomeProcess: " + mHomeProcess);
12688        }
12689        if (mPreviousProcess != null && (dumpPackage == null
12690                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12691            if (needSep) {
12692                pw.println();
12693                needSep = false;
12694            }
12695            pw.println("  mPreviousProcess: " + mPreviousProcess);
12696        }
12697        if (dumpAll) {
12698            StringBuilder sb = new StringBuilder(128);
12699            sb.append("  mPreviousProcessVisibleTime: ");
12700            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12701            pw.println(sb);
12702        }
12703        if (mHeavyWeightProcess != null && (dumpPackage == null
12704                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12705            if (needSep) {
12706                pw.println();
12707                needSep = false;
12708            }
12709            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12710        }
12711        if (dumpPackage == null) {
12712            pw.println("  mConfiguration: " + mConfiguration);
12713        }
12714        if (dumpAll) {
12715            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12716            if (mCompatModePackages.getPackages().size() > 0) {
12717                boolean printed = false;
12718                for (Map.Entry<String, Integer> entry
12719                        : mCompatModePackages.getPackages().entrySet()) {
12720                    String pkg = entry.getKey();
12721                    int mode = entry.getValue();
12722                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12723                        continue;
12724                    }
12725                    if (!printed) {
12726                        pw.println("  mScreenCompatPackages:");
12727                        printed = true;
12728                    }
12729                    pw.print("    "); pw.print(pkg); pw.print(": ");
12730                            pw.print(mode); pw.println();
12731                }
12732            }
12733        }
12734        if (dumpPackage == null) {
12735            if (mSleeping || mWentToSleep || mLockScreenShown) {
12736                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12737                        + " mLockScreenShown " + mLockScreenShown);
12738            }
12739            if (mShuttingDown || mRunningVoice) {
12740                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12741            }
12742        }
12743        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12744                || mOrigWaitForDebugger) {
12745            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12746                    || dumpPackage.equals(mOrigDebugApp)) {
12747                if (needSep) {
12748                    pw.println();
12749                    needSep = false;
12750                }
12751                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12752                        + " mDebugTransient=" + mDebugTransient
12753                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12754            }
12755        }
12756        if (mOpenGlTraceApp != null) {
12757            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12758                if (needSep) {
12759                    pw.println();
12760                    needSep = false;
12761                }
12762                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12763            }
12764        }
12765        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12766                || mProfileFd != null) {
12767            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12768                if (needSep) {
12769                    pw.println();
12770                    needSep = false;
12771                }
12772                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12773                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12774                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12775                        + mAutoStopProfiler);
12776                pw.println("  mProfileType=" + mProfileType);
12777            }
12778        }
12779        if (dumpPackage == null) {
12780            if (mAlwaysFinishActivities || mController != null) {
12781                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12782                        + " mController=" + mController);
12783            }
12784            if (dumpAll) {
12785                pw.println("  Total persistent processes: " + numPers);
12786                pw.println("  mProcessesReady=" + mProcessesReady
12787                        + " mSystemReady=" + mSystemReady);
12788                pw.println("  mBooting=" + mBooting
12789                        + " mBooted=" + mBooted
12790                        + " mFactoryTest=" + mFactoryTest);
12791                pw.print("  mLastPowerCheckRealtime=");
12792                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12793                        pw.println("");
12794                pw.print("  mLastPowerCheckUptime=");
12795                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12796                        pw.println("");
12797                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12798                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12799                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12800                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12801                        + " (" + mLruProcesses.size() + " total)"
12802                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12803                        + " mNumServiceProcs=" + mNumServiceProcs
12804                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12805                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12806                        + " mLastMemoryLevel" + mLastMemoryLevel
12807                        + " mLastNumProcesses" + mLastNumProcesses);
12808                long now = SystemClock.uptimeMillis();
12809                pw.print("  mLastIdleTime=");
12810                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12811                        pw.print(" mLowRamSinceLastIdle=");
12812                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12813                        pw.println();
12814            }
12815        }
12816
12817        if (!printedAnything) {
12818            pw.println("  (nothing)");
12819        }
12820    }
12821
12822    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12823            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12824        if (mProcessesToGc.size() > 0) {
12825            boolean printed = false;
12826            long now = SystemClock.uptimeMillis();
12827            for (int i=0; i<mProcessesToGc.size(); i++) {
12828                ProcessRecord proc = mProcessesToGc.get(i);
12829                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12830                    continue;
12831                }
12832                if (!printed) {
12833                    if (needSep) pw.println();
12834                    needSep = true;
12835                    pw.println("  Processes that are waiting to GC:");
12836                    printed = true;
12837                }
12838                pw.print("    Process "); pw.println(proc);
12839                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12840                        pw.print(", last gced=");
12841                        pw.print(now-proc.lastRequestedGc);
12842                        pw.print(" ms ago, last lowMem=");
12843                        pw.print(now-proc.lastLowMemory);
12844                        pw.println(" ms ago");
12845
12846            }
12847        }
12848        return needSep;
12849    }
12850
12851    void printOomLevel(PrintWriter pw, String name, int adj) {
12852        pw.print("    ");
12853        if (adj >= 0) {
12854            pw.print(' ');
12855            if (adj < 10) pw.print(' ');
12856        } else {
12857            if (adj > -10) pw.print(' ');
12858        }
12859        pw.print(adj);
12860        pw.print(": ");
12861        pw.print(name);
12862        pw.print(" (");
12863        pw.print(mProcessList.getMemLevel(adj)/1024);
12864        pw.println(" kB)");
12865    }
12866
12867    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12868            int opti, boolean dumpAll) {
12869        boolean needSep = false;
12870
12871        if (mLruProcesses.size() > 0) {
12872            if (needSep) pw.println();
12873            needSep = true;
12874            pw.println("  OOM levels:");
12875            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12876            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12877            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12878            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12879            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12880            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12881            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12882            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12883            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12884            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12885            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12886            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12887            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12888
12889            if (needSep) pw.println();
12890            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12891                    pw.print(" total, non-act at ");
12892                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12893                    pw.print(", non-svc at ");
12894                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12895                    pw.println("):");
12896            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12897            needSep = true;
12898        }
12899
12900        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12901
12902        pw.println();
12903        pw.println("  mHomeProcess: " + mHomeProcess);
12904        pw.println("  mPreviousProcess: " + mPreviousProcess);
12905        if (mHeavyWeightProcess != null) {
12906            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12907        }
12908
12909        return true;
12910    }
12911
12912    /**
12913     * There are three ways to call this:
12914     *  - no provider specified: dump all the providers
12915     *  - a flattened component name that matched an existing provider was specified as the
12916     *    first arg: dump that one provider
12917     *  - the first arg isn't the flattened component name of an existing provider:
12918     *    dump all providers whose component contains the first arg as a substring
12919     */
12920    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12921            int opti, boolean dumpAll) {
12922        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12923    }
12924
12925    static class ItemMatcher {
12926        ArrayList<ComponentName> components;
12927        ArrayList<String> strings;
12928        ArrayList<Integer> objects;
12929        boolean all;
12930
12931        ItemMatcher() {
12932            all = true;
12933        }
12934
12935        void build(String name) {
12936            ComponentName componentName = ComponentName.unflattenFromString(name);
12937            if (componentName != null) {
12938                if (components == null) {
12939                    components = new ArrayList<ComponentName>();
12940                }
12941                components.add(componentName);
12942                all = false;
12943            } else {
12944                int objectId = 0;
12945                // Not a '/' separated full component name; maybe an object ID?
12946                try {
12947                    objectId = Integer.parseInt(name, 16);
12948                    if (objects == null) {
12949                        objects = new ArrayList<Integer>();
12950                    }
12951                    objects.add(objectId);
12952                    all = false;
12953                } catch (RuntimeException e) {
12954                    // Not an integer; just do string match.
12955                    if (strings == null) {
12956                        strings = new ArrayList<String>();
12957                    }
12958                    strings.add(name);
12959                    all = false;
12960                }
12961            }
12962        }
12963
12964        int build(String[] args, int opti) {
12965            for (; opti<args.length; opti++) {
12966                String name = args[opti];
12967                if ("--".equals(name)) {
12968                    return opti+1;
12969                }
12970                build(name);
12971            }
12972            return opti;
12973        }
12974
12975        boolean match(Object object, ComponentName comp) {
12976            if (all) {
12977                return true;
12978            }
12979            if (components != null) {
12980                for (int i=0; i<components.size(); i++) {
12981                    if (components.get(i).equals(comp)) {
12982                        return true;
12983                    }
12984                }
12985            }
12986            if (objects != null) {
12987                for (int i=0; i<objects.size(); i++) {
12988                    if (System.identityHashCode(object) == objects.get(i)) {
12989                        return true;
12990                    }
12991                }
12992            }
12993            if (strings != null) {
12994                String flat = comp.flattenToString();
12995                for (int i=0; i<strings.size(); i++) {
12996                    if (flat.contains(strings.get(i))) {
12997                        return true;
12998                    }
12999                }
13000            }
13001            return false;
13002        }
13003    }
13004
13005    /**
13006     * There are three things that cmd can be:
13007     *  - a flattened component name that matches an existing activity
13008     *  - the cmd arg isn't the flattened component name of an existing activity:
13009     *    dump all activity whose component contains the cmd as a substring
13010     *  - A hex number of the ActivityRecord object instance.
13011     */
13012    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13013            int opti, boolean dumpAll) {
13014        ArrayList<ActivityRecord> activities;
13015
13016        synchronized (this) {
13017            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13018        }
13019
13020        if (activities.size() <= 0) {
13021            return false;
13022        }
13023
13024        String[] newArgs = new String[args.length - opti];
13025        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13026
13027        TaskRecord lastTask = null;
13028        boolean needSep = false;
13029        for (int i=activities.size()-1; i>=0; i--) {
13030            ActivityRecord r = activities.get(i);
13031            if (needSep) {
13032                pw.println();
13033            }
13034            needSep = true;
13035            synchronized (this) {
13036                if (lastTask != r.task) {
13037                    lastTask = r.task;
13038                    pw.print("TASK "); pw.print(lastTask.affinity);
13039                            pw.print(" id="); pw.println(lastTask.taskId);
13040                    if (dumpAll) {
13041                        lastTask.dump(pw, "  ");
13042                    }
13043                }
13044            }
13045            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13046        }
13047        return true;
13048    }
13049
13050    /**
13051     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13052     * there is a thread associated with the activity.
13053     */
13054    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13055            final ActivityRecord r, String[] args, boolean dumpAll) {
13056        String innerPrefix = prefix + "  ";
13057        synchronized (this) {
13058            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13059                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13060                    pw.print(" pid=");
13061                    if (r.app != null) pw.println(r.app.pid);
13062                    else pw.println("(not running)");
13063            if (dumpAll) {
13064                r.dump(pw, innerPrefix);
13065            }
13066        }
13067        if (r.app != null && r.app.thread != null) {
13068            // flush anything that is already in the PrintWriter since the thread is going
13069            // to write to the file descriptor directly
13070            pw.flush();
13071            try {
13072                TransferPipe tp = new TransferPipe();
13073                try {
13074                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13075                            r.appToken, innerPrefix, args);
13076                    tp.go(fd);
13077                } finally {
13078                    tp.kill();
13079                }
13080            } catch (IOException e) {
13081                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13082            } catch (RemoteException e) {
13083                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13084            }
13085        }
13086    }
13087
13088    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13089            int opti, boolean dumpAll, String dumpPackage) {
13090        boolean needSep = false;
13091        boolean onlyHistory = false;
13092        boolean printedAnything = false;
13093
13094        if ("history".equals(dumpPackage)) {
13095            if (opti < args.length && "-s".equals(args[opti])) {
13096                dumpAll = false;
13097            }
13098            onlyHistory = true;
13099            dumpPackage = null;
13100        }
13101
13102        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13103        if (!onlyHistory && dumpAll) {
13104            if (mRegisteredReceivers.size() > 0) {
13105                boolean printed = false;
13106                Iterator it = mRegisteredReceivers.values().iterator();
13107                while (it.hasNext()) {
13108                    ReceiverList r = (ReceiverList)it.next();
13109                    if (dumpPackage != null && (r.app == null ||
13110                            !dumpPackage.equals(r.app.info.packageName))) {
13111                        continue;
13112                    }
13113                    if (!printed) {
13114                        pw.println("  Registered Receivers:");
13115                        needSep = true;
13116                        printed = true;
13117                        printedAnything = true;
13118                    }
13119                    pw.print("  * "); pw.println(r);
13120                    r.dump(pw, "    ");
13121                }
13122            }
13123
13124            if (mReceiverResolver.dump(pw, needSep ?
13125                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13126                    "    ", dumpPackage, false)) {
13127                needSep = true;
13128                printedAnything = true;
13129            }
13130        }
13131
13132        for (BroadcastQueue q : mBroadcastQueues) {
13133            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13134            printedAnything |= needSep;
13135        }
13136
13137        needSep = true;
13138
13139        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13140            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13141                if (needSep) {
13142                    pw.println();
13143                }
13144                needSep = true;
13145                printedAnything = true;
13146                pw.print("  Sticky broadcasts for user ");
13147                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13148                StringBuilder sb = new StringBuilder(128);
13149                for (Map.Entry<String, ArrayList<Intent>> ent
13150                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13151                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13152                    if (dumpAll) {
13153                        pw.println(":");
13154                        ArrayList<Intent> intents = ent.getValue();
13155                        final int N = intents.size();
13156                        for (int i=0; i<N; i++) {
13157                            sb.setLength(0);
13158                            sb.append("    Intent: ");
13159                            intents.get(i).toShortString(sb, false, true, false, false);
13160                            pw.println(sb.toString());
13161                            Bundle bundle = intents.get(i).getExtras();
13162                            if (bundle != null) {
13163                                pw.print("      ");
13164                                pw.println(bundle.toString());
13165                            }
13166                        }
13167                    } else {
13168                        pw.println("");
13169                    }
13170                }
13171            }
13172        }
13173
13174        if (!onlyHistory && dumpAll) {
13175            pw.println();
13176            for (BroadcastQueue queue : mBroadcastQueues) {
13177                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13178                        + queue.mBroadcastsScheduled);
13179            }
13180            pw.println("  mHandler:");
13181            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13182            needSep = true;
13183            printedAnything = true;
13184        }
13185
13186        if (!printedAnything) {
13187            pw.println("  (nothing)");
13188        }
13189    }
13190
13191    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13192            int opti, boolean dumpAll, String dumpPackage) {
13193        boolean needSep;
13194        boolean printedAnything = false;
13195
13196        ItemMatcher matcher = new ItemMatcher();
13197        matcher.build(args, opti);
13198
13199        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13200
13201        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13202        printedAnything |= needSep;
13203
13204        if (mLaunchingProviders.size() > 0) {
13205            boolean printed = false;
13206            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13207                ContentProviderRecord r = mLaunchingProviders.get(i);
13208                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13209                    continue;
13210                }
13211                if (!printed) {
13212                    if (needSep) pw.println();
13213                    needSep = true;
13214                    pw.println("  Launching content providers:");
13215                    printed = true;
13216                    printedAnything = true;
13217                }
13218                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13219                        pw.println(r);
13220            }
13221        }
13222
13223        if (mGrantedUriPermissions.size() > 0) {
13224            boolean printed = false;
13225            int dumpUid = -2;
13226            if (dumpPackage != null) {
13227                try {
13228                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13229                } catch (NameNotFoundException e) {
13230                    dumpUid = -1;
13231                }
13232            }
13233            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13234                int uid = mGrantedUriPermissions.keyAt(i);
13235                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13236                    continue;
13237                }
13238                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13239                if (!printed) {
13240                    if (needSep) pw.println();
13241                    needSep = true;
13242                    pw.println("  Granted Uri Permissions:");
13243                    printed = true;
13244                    printedAnything = true;
13245                }
13246                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13247                for (UriPermission perm : perms.values()) {
13248                    pw.print("    "); pw.println(perm);
13249                    if (dumpAll) {
13250                        perm.dump(pw, "      ");
13251                    }
13252                }
13253            }
13254        }
13255
13256        if (!printedAnything) {
13257            pw.println("  (nothing)");
13258        }
13259    }
13260
13261    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13262            int opti, boolean dumpAll, String dumpPackage) {
13263        boolean printed = false;
13264
13265        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13266
13267        if (mIntentSenderRecords.size() > 0) {
13268            Iterator<WeakReference<PendingIntentRecord>> it
13269                    = mIntentSenderRecords.values().iterator();
13270            while (it.hasNext()) {
13271                WeakReference<PendingIntentRecord> ref = it.next();
13272                PendingIntentRecord rec = ref != null ? ref.get(): null;
13273                if (dumpPackage != null && (rec == null
13274                        || !dumpPackage.equals(rec.key.packageName))) {
13275                    continue;
13276                }
13277                printed = true;
13278                if (rec != null) {
13279                    pw.print("  * "); pw.println(rec);
13280                    if (dumpAll) {
13281                        rec.dump(pw, "    ");
13282                    }
13283                } else {
13284                    pw.print("  * "); pw.println(ref);
13285                }
13286            }
13287        }
13288
13289        if (!printed) {
13290            pw.println("  (nothing)");
13291        }
13292    }
13293
13294    private static final int dumpProcessList(PrintWriter pw,
13295            ActivityManagerService service, List list,
13296            String prefix, String normalLabel, String persistentLabel,
13297            String dumpPackage) {
13298        int numPers = 0;
13299        final int N = list.size()-1;
13300        for (int i=N; i>=0; i--) {
13301            ProcessRecord r = (ProcessRecord)list.get(i);
13302            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13303                continue;
13304            }
13305            pw.println(String.format("%s%s #%2d: %s",
13306                    prefix, (r.persistent ? persistentLabel : normalLabel),
13307                    i, r.toString()));
13308            if (r.persistent) {
13309                numPers++;
13310            }
13311        }
13312        return numPers;
13313    }
13314
13315    private static final boolean dumpProcessOomList(PrintWriter pw,
13316            ActivityManagerService service, List<ProcessRecord> origList,
13317            String prefix, String normalLabel, String persistentLabel,
13318            boolean inclDetails, String dumpPackage) {
13319
13320        ArrayList<Pair<ProcessRecord, Integer>> list
13321                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13322        for (int i=0; i<origList.size(); i++) {
13323            ProcessRecord r = origList.get(i);
13324            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13325                continue;
13326            }
13327            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13328        }
13329
13330        if (list.size() <= 0) {
13331            return false;
13332        }
13333
13334        Comparator<Pair<ProcessRecord, Integer>> comparator
13335                = new Comparator<Pair<ProcessRecord, Integer>>() {
13336            @Override
13337            public int compare(Pair<ProcessRecord, Integer> object1,
13338                    Pair<ProcessRecord, Integer> object2) {
13339                if (object1.first.setAdj != object2.first.setAdj) {
13340                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13341                }
13342                if (object1.second.intValue() != object2.second.intValue()) {
13343                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13344                }
13345                return 0;
13346            }
13347        };
13348
13349        Collections.sort(list, comparator);
13350
13351        final long curRealtime = SystemClock.elapsedRealtime();
13352        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13353        final long curUptime = SystemClock.uptimeMillis();
13354        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13355
13356        for (int i=list.size()-1; i>=0; i--) {
13357            ProcessRecord r = list.get(i).first;
13358            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13359            char schedGroup;
13360            switch (r.setSchedGroup) {
13361                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13362                    schedGroup = 'B';
13363                    break;
13364                case Process.THREAD_GROUP_DEFAULT:
13365                    schedGroup = 'F';
13366                    break;
13367                default:
13368                    schedGroup = '?';
13369                    break;
13370            }
13371            char foreground;
13372            if (r.foregroundActivities) {
13373                foreground = 'A';
13374            } else if (r.foregroundServices) {
13375                foreground = 'S';
13376            } else {
13377                foreground = ' ';
13378            }
13379            String procState = ProcessList.makeProcStateString(r.curProcState);
13380            pw.print(prefix);
13381            pw.print(r.persistent ? persistentLabel : normalLabel);
13382            pw.print(" #");
13383            int num = (origList.size()-1)-list.get(i).second;
13384            if (num < 10) pw.print(' ');
13385            pw.print(num);
13386            pw.print(": ");
13387            pw.print(oomAdj);
13388            pw.print(' ');
13389            pw.print(schedGroup);
13390            pw.print('/');
13391            pw.print(foreground);
13392            pw.print('/');
13393            pw.print(procState);
13394            pw.print(" trm:");
13395            if (r.trimMemoryLevel < 10) pw.print(' ');
13396            pw.print(r.trimMemoryLevel);
13397            pw.print(' ');
13398            pw.print(r.toShortString());
13399            pw.print(" (");
13400            pw.print(r.adjType);
13401            pw.println(')');
13402            if (r.adjSource != null || r.adjTarget != null) {
13403                pw.print(prefix);
13404                pw.print("    ");
13405                if (r.adjTarget instanceof ComponentName) {
13406                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13407                } else if (r.adjTarget != null) {
13408                    pw.print(r.adjTarget.toString());
13409                } else {
13410                    pw.print("{null}");
13411                }
13412                pw.print("<=");
13413                if (r.adjSource instanceof ProcessRecord) {
13414                    pw.print("Proc{");
13415                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13416                    pw.println("}");
13417                } else if (r.adjSource != null) {
13418                    pw.println(r.adjSource.toString());
13419                } else {
13420                    pw.println("{null}");
13421                }
13422            }
13423            if (inclDetails) {
13424                pw.print(prefix);
13425                pw.print("    ");
13426                pw.print("oom: max="); pw.print(r.maxAdj);
13427                pw.print(" curRaw="); pw.print(r.curRawAdj);
13428                pw.print(" setRaw="); pw.print(r.setRawAdj);
13429                pw.print(" cur="); pw.print(r.curAdj);
13430                pw.print(" set="); pw.println(r.setAdj);
13431                pw.print(prefix);
13432                pw.print("    ");
13433                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13434                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13435                pw.print(" lastPss="); pw.print(r.lastPss);
13436                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13437                pw.print(prefix);
13438                pw.print("    ");
13439                pw.print("cached="); pw.print(r.cached);
13440                pw.print(" empty="); pw.print(r.empty);
13441                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13442
13443                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13444                    if (r.lastWakeTime != 0) {
13445                        long wtime;
13446                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13447                        synchronized (stats) {
13448                            wtime = stats.getProcessWakeTime(r.info.uid,
13449                                    r.pid, curRealtime);
13450                        }
13451                        long timeUsed = wtime - r.lastWakeTime;
13452                        pw.print(prefix);
13453                        pw.print("    ");
13454                        pw.print("keep awake over ");
13455                        TimeUtils.formatDuration(realtimeSince, pw);
13456                        pw.print(" used ");
13457                        TimeUtils.formatDuration(timeUsed, pw);
13458                        pw.print(" (");
13459                        pw.print((timeUsed*100)/realtimeSince);
13460                        pw.println("%)");
13461                    }
13462                    if (r.lastCpuTime != 0) {
13463                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13464                        pw.print(prefix);
13465                        pw.print("    ");
13466                        pw.print("run cpu over ");
13467                        TimeUtils.formatDuration(uptimeSince, pw);
13468                        pw.print(" used ");
13469                        TimeUtils.formatDuration(timeUsed, pw);
13470                        pw.print(" (");
13471                        pw.print((timeUsed*100)/uptimeSince);
13472                        pw.println("%)");
13473                    }
13474                }
13475            }
13476        }
13477        return true;
13478    }
13479
13480    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13481        ArrayList<ProcessRecord> procs;
13482        synchronized (this) {
13483            if (args != null && args.length > start
13484                    && args[start].charAt(0) != '-') {
13485                procs = new ArrayList<ProcessRecord>();
13486                int pid = -1;
13487                try {
13488                    pid = Integer.parseInt(args[start]);
13489                } catch (NumberFormatException e) {
13490                }
13491                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13492                    ProcessRecord proc = mLruProcesses.get(i);
13493                    if (proc.pid == pid) {
13494                        procs.add(proc);
13495                    } else if (proc.processName.equals(args[start])) {
13496                        procs.add(proc);
13497                    }
13498                }
13499                if (procs.size() <= 0) {
13500                    return null;
13501                }
13502            } else {
13503                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13504            }
13505        }
13506        return procs;
13507    }
13508
13509    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13510            PrintWriter pw, String[] args) {
13511        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13512        if (procs == null) {
13513            pw.println("No process found for: " + args[0]);
13514            return;
13515        }
13516
13517        long uptime = SystemClock.uptimeMillis();
13518        long realtime = SystemClock.elapsedRealtime();
13519        pw.println("Applications Graphics Acceleration Info:");
13520        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13521
13522        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13523            ProcessRecord r = procs.get(i);
13524            if (r.thread != null) {
13525                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13526                pw.flush();
13527                try {
13528                    TransferPipe tp = new TransferPipe();
13529                    try {
13530                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13531                        tp.go(fd);
13532                    } finally {
13533                        tp.kill();
13534                    }
13535                } catch (IOException e) {
13536                    pw.println("Failure while dumping the app: " + r);
13537                    pw.flush();
13538                } catch (RemoteException e) {
13539                    pw.println("Got a RemoteException while dumping the app " + r);
13540                    pw.flush();
13541                }
13542            }
13543        }
13544    }
13545
13546    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13547        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13548        if (procs == null) {
13549            pw.println("No process found for: " + args[0]);
13550            return;
13551        }
13552
13553        pw.println("Applications Database Info:");
13554
13555        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13556            ProcessRecord r = procs.get(i);
13557            if (r.thread != null) {
13558                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13559                pw.flush();
13560                try {
13561                    TransferPipe tp = new TransferPipe();
13562                    try {
13563                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13564                        tp.go(fd);
13565                    } finally {
13566                        tp.kill();
13567                    }
13568                } catch (IOException e) {
13569                    pw.println("Failure while dumping the app: " + r);
13570                    pw.flush();
13571                } catch (RemoteException e) {
13572                    pw.println("Got a RemoteException while dumping the app " + r);
13573                    pw.flush();
13574                }
13575            }
13576        }
13577    }
13578
13579    final static class MemItem {
13580        final boolean isProc;
13581        final String label;
13582        final String shortLabel;
13583        final long pss;
13584        final int id;
13585        final boolean hasActivities;
13586        ArrayList<MemItem> subitems;
13587
13588        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13589                boolean _hasActivities) {
13590            isProc = true;
13591            label = _label;
13592            shortLabel = _shortLabel;
13593            pss = _pss;
13594            id = _id;
13595            hasActivities = _hasActivities;
13596        }
13597
13598        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13599            isProc = false;
13600            label = _label;
13601            shortLabel = _shortLabel;
13602            pss = _pss;
13603            id = _id;
13604            hasActivities = false;
13605        }
13606    }
13607
13608    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13609            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13610        if (sort && !isCompact) {
13611            Collections.sort(items, new Comparator<MemItem>() {
13612                @Override
13613                public int compare(MemItem lhs, MemItem rhs) {
13614                    if (lhs.pss < rhs.pss) {
13615                        return 1;
13616                    } else if (lhs.pss > rhs.pss) {
13617                        return -1;
13618                    }
13619                    return 0;
13620                }
13621            });
13622        }
13623
13624        for (int i=0; i<items.size(); i++) {
13625            MemItem mi = items.get(i);
13626            if (!isCompact) {
13627                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13628            } else if (mi.isProc) {
13629                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13630                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13631                pw.println(mi.hasActivities ? ",a" : ",e");
13632            } else {
13633                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13634                pw.println(mi.pss);
13635            }
13636            if (mi.subitems != null) {
13637                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13638                        true, isCompact);
13639            }
13640        }
13641    }
13642
13643    // These are in KB.
13644    static final long[] DUMP_MEM_BUCKETS = new long[] {
13645        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13646        120*1024, 160*1024, 200*1024,
13647        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13648        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13649    };
13650
13651    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13652            boolean stackLike) {
13653        int start = label.lastIndexOf('.');
13654        if (start >= 0) start++;
13655        else start = 0;
13656        int end = label.length();
13657        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13658            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13659                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13660                out.append(bucket);
13661                out.append(stackLike ? "MB." : "MB ");
13662                out.append(label, start, end);
13663                return;
13664            }
13665        }
13666        out.append(memKB/1024);
13667        out.append(stackLike ? "MB." : "MB ");
13668        out.append(label, start, end);
13669    }
13670
13671    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13672            ProcessList.NATIVE_ADJ,
13673            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13674            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13675            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13676            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13677            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13678    };
13679    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13680            "Native",
13681            "System", "Persistent", "Foreground",
13682            "Visible", "Perceptible",
13683            "Heavy Weight", "Backup",
13684            "A Services", "Home",
13685            "Previous", "B Services", "Cached"
13686    };
13687    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13688            "native",
13689            "sys", "pers", "fore",
13690            "vis", "percept",
13691            "heavy", "backup",
13692            "servicea", "home",
13693            "prev", "serviceb", "cached"
13694    };
13695
13696    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13697            long realtime, boolean isCheckinRequest, boolean isCompact) {
13698        if (isCheckinRequest || isCompact) {
13699            // short checkin version
13700            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13701        } else {
13702            pw.println("Applications Memory Usage (kB):");
13703            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13704        }
13705    }
13706
13707    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13708            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13709        boolean dumpDetails = false;
13710        boolean dumpFullDetails = false;
13711        boolean dumpDalvik = false;
13712        boolean oomOnly = false;
13713        boolean isCompact = false;
13714        boolean localOnly = false;
13715
13716        int opti = 0;
13717        while (opti < args.length) {
13718            String opt = args[opti];
13719            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13720                break;
13721            }
13722            opti++;
13723            if ("-a".equals(opt)) {
13724                dumpDetails = true;
13725                dumpFullDetails = true;
13726                dumpDalvik = true;
13727            } else if ("-d".equals(opt)) {
13728                dumpDalvik = true;
13729            } else if ("-c".equals(opt)) {
13730                isCompact = true;
13731            } else if ("--oom".equals(opt)) {
13732                oomOnly = true;
13733            } else if ("--local".equals(opt)) {
13734                localOnly = true;
13735            } else if ("-h".equals(opt)) {
13736                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13737                pw.println("  -a: include all available information for each process.");
13738                pw.println("  -d: include dalvik details when dumping process details.");
13739                pw.println("  -c: dump in a compact machine-parseable representation.");
13740                pw.println("  --oom: only show processes organized by oom adj.");
13741                pw.println("  --local: only collect details locally, don't call process.");
13742                pw.println("If [process] is specified it can be the name or ");
13743                pw.println("pid of a specific process to dump.");
13744                return;
13745            } else {
13746                pw.println("Unknown argument: " + opt + "; use -h for help");
13747            }
13748        }
13749
13750        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13751        long uptime = SystemClock.uptimeMillis();
13752        long realtime = SystemClock.elapsedRealtime();
13753        final long[] tmpLong = new long[1];
13754
13755        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13756        if (procs == null) {
13757            // No Java processes.  Maybe they want to print a native process.
13758            if (args != null && args.length > opti
13759                    && args[opti].charAt(0) != '-') {
13760                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13761                        = new ArrayList<ProcessCpuTracker.Stats>();
13762                updateCpuStatsNow();
13763                int findPid = -1;
13764                try {
13765                    findPid = Integer.parseInt(args[opti]);
13766                } catch (NumberFormatException e) {
13767                }
13768                synchronized (mProcessCpuTracker) {
13769                    final int N = mProcessCpuTracker.countStats();
13770                    for (int i=0; i<N; i++) {
13771                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13772                        if (st.pid == findPid || (st.baseName != null
13773                                && st.baseName.equals(args[opti]))) {
13774                            nativeProcs.add(st);
13775                        }
13776                    }
13777                }
13778                if (nativeProcs.size() > 0) {
13779                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13780                            isCompact);
13781                    Debug.MemoryInfo mi = null;
13782                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13783                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13784                        final int pid = r.pid;
13785                        if (!isCheckinRequest && dumpDetails) {
13786                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13787                        }
13788                        if (mi == null) {
13789                            mi = new Debug.MemoryInfo();
13790                        }
13791                        if (dumpDetails || (!brief && !oomOnly)) {
13792                            Debug.getMemoryInfo(pid, mi);
13793                        } else {
13794                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13795                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13796                        }
13797                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13798                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13799                        if (isCheckinRequest) {
13800                            pw.println();
13801                        }
13802                    }
13803                    return;
13804                }
13805            }
13806            pw.println("No process found for: " + args[opti]);
13807            return;
13808        }
13809
13810        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13811            dumpDetails = true;
13812        }
13813
13814        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13815
13816        String[] innerArgs = new String[args.length-opti];
13817        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13818
13819        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13820        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13821        long nativePss=0, dalvikPss=0, otherPss=0;
13822        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13823
13824        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13825        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13826                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13827
13828        long totalPss = 0;
13829        long cachedPss = 0;
13830
13831        Debug.MemoryInfo mi = null;
13832        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13833            final ProcessRecord r = procs.get(i);
13834            final IApplicationThread thread;
13835            final int pid;
13836            final int oomAdj;
13837            final boolean hasActivities;
13838            synchronized (this) {
13839                thread = r.thread;
13840                pid = r.pid;
13841                oomAdj = r.getSetAdjWithServices();
13842                hasActivities = r.activities.size() > 0;
13843            }
13844            if (thread != null) {
13845                if (!isCheckinRequest && dumpDetails) {
13846                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13847                }
13848                if (mi == null) {
13849                    mi = new Debug.MemoryInfo();
13850                }
13851                if (dumpDetails || (!brief && !oomOnly)) {
13852                    Debug.getMemoryInfo(pid, mi);
13853                } else {
13854                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13855                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13856                }
13857                if (dumpDetails) {
13858                    if (localOnly) {
13859                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13860                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13861                        if (isCheckinRequest) {
13862                            pw.println();
13863                        }
13864                    } else {
13865                        try {
13866                            pw.flush();
13867                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13868                                    dumpDalvik, innerArgs);
13869                        } catch (RemoteException e) {
13870                            if (!isCheckinRequest) {
13871                                pw.println("Got RemoteException!");
13872                                pw.flush();
13873                            }
13874                        }
13875                    }
13876                }
13877
13878                final long myTotalPss = mi.getTotalPss();
13879                final long myTotalUss = mi.getTotalUss();
13880
13881                synchronized (this) {
13882                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13883                        // Record this for posterity if the process has been stable.
13884                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13885                    }
13886                }
13887
13888                if (!isCheckinRequest && mi != null) {
13889                    totalPss += myTotalPss;
13890                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13891                            (hasActivities ? " / activities)" : ")"),
13892                            r.processName, myTotalPss, pid, hasActivities);
13893                    procMems.add(pssItem);
13894                    procMemsMap.put(pid, pssItem);
13895
13896                    nativePss += mi.nativePss;
13897                    dalvikPss += mi.dalvikPss;
13898                    otherPss += mi.otherPss;
13899                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13900                        long mem = mi.getOtherPss(j);
13901                        miscPss[j] += mem;
13902                        otherPss -= mem;
13903                    }
13904
13905                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13906                        cachedPss += myTotalPss;
13907                    }
13908
13909                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13910                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13911                                || oomIndex == (oomPss.length-1)) {
13912                            oomPss[oomIndex] += myTotalPss;
13913                            if (oomProcs[oomIndex] == null) {
13914                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13915                            }
13916                            oomProcs[oomIndex].add(pssItem);
13917                            break;
13918                        }
13919                    }
13920                }
13921            }
13922        }
13923
13924        long nativeProcTotalPss = 0;
13925
13926        if (!isCheckinRequest && procs.size() > 1) {
13927            // If we are showing aggregations, also look for native processes to
13928            // include so that our aggregations are more accurate.
13929            updateCpuStatsNow();
13930            synchronized (mProcessCpuTracker) {
13931                final int N = mProcessCpuTracker.countStats();
13932                for (int i=0; i<N; i++) {
13933                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13934                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13935                        if (mi == null) {
13936                            mi = new Debug.MemoryInfo();
13937                        }
13938                        if (!brief && !oomOnly) {
13939                            Debug.getMemoryInfo(st.pid, mi);
13940                        } else {
13941                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13942                            mi.nativePrivateDirty = (int)tmpLong[0];
13943                        }
13944
13945                        final long myTotalPss = mi.getTotalPss();
13946                        totalPss += myTotalPss;
13947                        nativeProcTotalPss += myTotalPss;
13948
13949                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13950                                st.name, myTotalPss, st.pid, false);
13951                        procMems.add(pssItem);
13952
13953                        nativePss += mi.nativePss;
13954                        dalvikPss += mi.dalvikPss;
13955                        otherPss += mi.otherPss;
13956                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13957                            long mem = mi.getOtherPss(j);
13958                            miscPss[j] += mem;
13959                            otherPss -= mem;
13960                        }
13961                        oomPss[0] += myTotalPss;
13962                        if (oomProcs[0] == null) {
13963                            oomProcs[0] = new ArrayList<MemItem>();
13964                        }
13965                        oomProcs[0].add(pssItem);
13966                    }
13967                }
13968            }
13969
13970            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13971
13972            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13973            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13974            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13975            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13976                String label = Debug.MemoryInfo.getOtherLabel(j);
13977                catMems.add(new MemItem(label, label, miscPss[j], j));
13978            }
13979
13980            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13981            for (int j=0; j<oomPss.length; j++) {
13982                if (oomPss[j] != 0) {
13983                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13984                            : DUMP_MEM_OOM_LABEL[j];
13985                    MemItem item = new MemItem(label, label, oomPss[j],
13986                            DUMP_MEM_OOM_ADJ[j]);
13987                    item.subitems = oomProcs[j];
13988                    oomMems.add(item);
13989                }
13990            }
13991
13992            if (!brief && !oomOnly && !isCompact) {
13993                pw.println();
13994                pw.println("Total PSS by process:");
13995                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13996                pw.println();
13997            }
13998            if (!isCompact) {
13999                pw.println("Total PSS by OOM adjustment:");
14000            }
14001            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14002            if (!brief && !oomOnly) {
14003                PrintWriter out = categoryPw != null ? categoryPw : pw;
14004                if (!isCompact) {
14005                    out.println();
14006                    out.println("Total PSS by category:");
14007                }
14008                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14009            }
14010            if (!isCompact) {
14011                pw.println();
14012            }
14013            MemInfoReader memInfo = new MemInfoReader();
14014            memInfo.readMemInfo();
14015            if (nativeProcTotalPss > 0) {
14016                synchronized (this) {
14017                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14018                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14019                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14020                            nativeProcTotalPss);
14021                }
14022            }
14023            if (!brief) {
14024                if (!isCompact) {
14025                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14026                    pw.print(" kB (status ");
14027                    switch (mLastMemoryLevel) {
14028                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14029                            pw.println("normal)");
14030                            break;
14031                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14032                            pw.println("moderate)");
14033                            break;
14034                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14035                            pw.println("low)");
14036                            break;
14037                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14038                            pw.println("critical)");
14039                            break;
14040                        default:
14041                            pw.print(mLastMemoryLevel);
14042                            pw.println(")");
14043                            break;
14044                    }
14045                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14046                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14047                            pw.print(cachedPss); pw.print(" cached pss + ");
14048                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14049                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14050                } else {
14051                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14052                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14053                            + memInfo.getFreeSizeKb()); pw.print(",");
14054                    pw.println(totalPss - cachedPss);
14055                }
14056            }
14057            if (!isCompact) {
14058                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14059                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14060                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14061                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14062                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14063                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14064                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14065                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14066                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14067                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14068                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14069            }
14070            if (!brief) {
14071                if (memInfo.getZramTotalSizeKb() != 0) {
14072                    if (!isCompact) {
14073                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14074                                pw.print(" kB physical used for ");
14075                                pw.print(memInfo.getSwapTotalSizeKb()
14076                                        - memInfo.getSwapFreeSizeKb());
14077                                pw.print(" kB in swap (");
14078                                pw.print(memInfo.getSwapTotalSizeKb());
14079                                pw.println(" kB total swap)");
14080                    } else {
14081                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14082                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14083                                pw.println(memInfo.getSwapFreeSizeKb());
14084                    }
14085                }
14086                final int[] SINGLE_LONG_FORMAT = new int[] {
14087                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14088                };
14089                long[] longOut = new long[1];
14090                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14091                        SINGLE_LONG_FORMAT, null, longOut, null);
14092                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14093                longOut[0] = 0;
14094                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14095                        SINGLE_LONG_FORMAT, null, longOut, null);
14096                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14097                longOut[0] = 0;
14098                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14099                        SINGLE_LONG_FORMAT, null, longOut, null);
14100                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14101                longOut[0] = 0;
14102                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14103                        SINGLE_LONG_FORMAT, null, longOut, null);
14104                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14105                if (!isCompact) {
14106                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14107                        pw.print("      KSM: "); pw.print(sharing);
14108                                pw.print(" kB saved from shared ");
14109                                pw.print(shared); pw.println(" kB");
14110                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14111                                pw.print(voltile); pw.println(" kB volatile");
14112                    }
14113                    pw.print("   Tuning: ");
14114                    pw.print(ActivityManager.staticGetMemoryClass());
14115                    pw.print(" (large ");
14116                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14117                    pw.print("), oom ");
14118                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14119                    pw.print(" kB");
14120                    pw.print(", restore limit ");
14121                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14122                    pw.print(" kB");
14123                    if (ActivityManager.isLowRamDeviceStatic()) {
14124                        pw.print(" (low-ram)");
14125                    }
14126                    if (ActivityManager.isHighEndGfx()) {
14127                        pw.print(" (high-end-gfx)");
14128                    }
14129                    pw.println();
14130                } else {
14131                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14132                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14133                    pw.println(voltile);
14134                    pw.print("tuning,");
14135                    pw.print(ActivityManager.staticGetMemoryClass());
14136                    pw.print(',');
14137                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14138                    pw.print(',');
14139                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14140                    if (ActivityManager.isLowRamDeviceStatic()) {
14141                        pw.print(",low-ram");
14142                    }
14143                    if (ActivityManager.isHighEndGfx()) {
14144                        pw.print(",high-end-gfx");
14145                    }
14146                    pw.println();
14147                }
14148            }
14149        }
14150    }
14151
14152    /**
14153     * Searches array of arguments for the specified string
14154     * @param args array of argument strings
14155     * @param value value to search for
14156     * @return true if the value is contained in the array
14157     */
14158    private static boolean scanArgs(String[] args, String value) {
14159        if (args != null) {
14160            for (String arg : args) {
14161                if (value.equals(arg)) {
14162                    return true;
14163                }
14164            }
14165        }
14166        return false;
14167    }
14168
14169    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14170            ContentProviderRecord cpr, boolean always) {
14171        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14172
14173        if (!inLaunching || always) {
14174            synchronized (cpr) {
14175                cpr.launchingApp = null;
14176                cpr.notifyAll();
14177            }
14178            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14179            String names[] = cpr.info.authority.split(";");
14180            for (int j = 0; j < names.length; j++) {
14181                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14182            }
14183        }
14184
14185        for (int i=0; i<cpr.connections.size(); i++) {
14186            ContentProviderConnection conn = cpr.connections.get(i);
14187            if (conn.waiting) {
14188                // If this connection is waiting for the provider, then we don't
14189                // need to mess with its process unless we are always removing
14190                // or for some reason the provider is not currently launching.
14191                if (inLaunching && !always) {
14192                    continue;
14193                }
14194            }
14195            ProcessRecord capp = conn.client;
14196            conn.dead = true;
14197            if (conn.stableCount > 0) {
14198                if (!capp.persistent && capp.thread != null
14199                        && capp.pid != 0
14200                        && capp.pid != MY_PID) {
14201                    capp.kill("depends on provider "
14202                            + cpr.name.flattenToShortString()
14203                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14204                }
14205            } else if (capp.thread != null && conn.provider.provider != null) {
14206                try {
14207                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14208                } catch (RemoteException e) {
14209                }
14210                // In the protocol here, we don't expect the client to correctly
14211                // clean up this connection, we'll just remove it.
14212                cpr.connections.remove(i);
14213                conn.client.conProviders.remove(conn);
14214            }
14215        }
14216
14217        if (inLaunching && always) {
14218            mLaunchingProviders.remove(cpr);
14219        }
14220        return inLaunching;
14221    }
14222
14223    /**
14224     * Main code for cleaning up a process when it has gone away.  This is
14225     * called both as a result of the process dying, or directly when stopping
14226     * a process when running in single process mode.
14227     */
14228    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14229            boolean restarting, boolean allowRestart, int index) {
14230        if (index >= 0) {
14231            removeLruProcessLocked(app);
14232            ProcessList.remove(app.pid);
14233        }
14234
14235        mProcessesToGc.remove(app);
14236        mPendingPssProcesses.remove(app);
14237
14238        // Dismiss any open dialogs.
14239        if (app.crashDialog != null && !app.forceCrashReport) {
14240            app.crashDialog.dismiss();
14241            app.crashDialog = null;
14242        }
14243        if (app.anrDialog != null) {
14244            app.anrDialog.dismiss();
14245            app.anrDialog = null;
14246        }
14247        if (app.waitDialog != null) {
14248            app.waitDialog.dismiss();
14249            app.waitDialog = null;
14250        }
14251
14252        app.crashing = false;
14253        app.notResponding = false;
14254
14255        app.resetPackageList(mProcessStats);
14256        app.unlinkDeathRecipient();
14257        app.makeInactive(mProcessStats);
14258        app.waitingToKill = null;
14259        app.forcingToForeground = null;
14260        updateProcessForegroundLocked(app, false, false);
14261        app.foregroundActivities = false;
14262        app.hasShownUi = false;
14263        app.treatLikeActivity = false;
14264        app.hasAboveClient = false;
14265        app.hasClientActivities = false;
14266
14267        mServices.killServicesLocked(app, allowRestart);
14268
14269        boolean restart = false;
14270
14271        // Remove published content providers.
14272        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14273            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14274            final boolean always = app.bad || !allowRestart;
14275            if (removeDyingProviderLocked(app, cpr, always) || always) {
14276                // We left the provider in the launching list, need to
14277                // restart it.
14278                restart = true;
14279            }
14280
14281            cpr.provider = null;
14282            cpr.proc = null;
14283        }
14284        app.pubProviders.clear();
14285
14286        // Take care of any launching providers waiting for this process.
14287        if (checkAppInLaunchingProvidersLocked(app, false)) {
14288            restart = true;
14289        }
14290
14291        // Unregister from connected content providers.
14292        if (!app.conProviders.isEmpty()) {
14293            for (int i=0; i<app.conProviders.size(); i++) {
14294                ContentProviderConnection conn = app.conProviders.get(i);
14295                conn.provider.connections.remove(conn);
14296            }
14297            app.conProviders.clear();
14298        }
14299
14300        // At this point there may be remaining entries in mLaunchingProviders
14301        // where we were the only one waiting, so they are no longer of use.
14302        // Look for these and clean up if found.
14303        // XXX Commented out for now.  Trying to figure out a way to reproduce
14304        // the actual situation to identify what is actually going on.
14305        if (false) {
14306            for (int i=0; i<mLaunchingProviders.size(); i++) {
14307                ContentProviderRecord cpr = (ContentProviderRecord)
14308                        mLaunchingProviders.get(i);
14309                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14310                    synchronized (cpr) {
14311                        cpr.launchingApp = null;
14312                        cpr.notifyAll();
14313                    }
14314                }
14315            }
14316        }
14317
14318        skipCurrentReceiverLocked(app);
14319
14320        // Unregister any receivers.
14321        for (int i=app.receivers.size()-1; i>=0; i--) {
14322            removeReceiverLocked(app.receivers.valueAt(i));
14323        }
14324        app.receivers.clear();
14325
14326        // If the app is undergoing backup, tell the backup manager about it
14327        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14328            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14329                    + mBackupTarget.appInfo + " died during backup");
14330            try {
14331                IBackupManager bm = IBackupManager.Stub.asInterface(
14332                        ServiceManager.getService(Context.BACKUP_SERVICE));
14333                bm.agentDisconnected(app.info.packageName);
14334            } catch (RemoteException e) {
14335                // can't happen; backup manager is local
14336            }
14337        }
14338
14339        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14340            ProcessChangeItem item = mPendingProcessChanges.get(i);
14341            if (item.pid == app.pid) {
14342                mPendingProcessChanges.remove(i);
14343                mAvailProcessChanges.add(item);
14344            }
14345        }
14346        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14347
14348        // If the caller is restarting this app, then leave it in its
14349        // current lists and let the caller take care of it.
14350        if (restarting) {
14351            return;
14352        }
14353
14354        if (!app.persistent || app.isolated) {
14355            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14356                    "Removing non-persistent process during cleanup: " + app);
14357            mProcessNames.remove(app.processName, app.uid);
14358            mIsolatedProcesses.remove(app.uid);
14359            if (mHeavyWeightProcess == app) {
14360                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14361                        mHeavyWeightProcess.userId, 0));
14362                mHeavyWeightProcess = null;
14363            }
14364        } else if (!app.removed) {
14365            // This app is persistent, so we need to keep its record around.
14366            // If it is not already on the pending app list, add it there
14367            // and start a new process for it.
14368            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14369                mPersistentStartingProcesses.add(app);
14370                restart = true;
14371            }
14372        }
14373        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14374                "Clean-up removing on hold: " + app);
14375        mProcessesOnHold.remove(app);
14376
14377        if (app == mHomeProcess) {
14378            mHomeProcess = null;
14379        }
14380        if (app == mPreviousProcess) {
14381            mPreviousProcess = null;
14382        }
14383
14384        if (restart && !app.isolated) {
14385            // We have components that still need to be running in the
14386            // process, so re-launch it.
14387            mProcessNames.put(app.processName, app.uid, app);
14388            startProcessLocked(app, "restart", app.processName);
14389        } else if (app.pid > 0 && app.pid != MY_PID) {
14390            // Goodbye!
14391            boolean removed;
14392            synchronized (mPidsSelfLocked) {
14393                mPidsSelfLocked.remove(app.pid);
14394                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14395            }
14396            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14397            if (app.isolated) {
14398                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14399            }
14400            app.setPid(0);
14401        }
14402    }
14403
14404    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14405        // Look through the content providers we are waiting to have launched,
14406        // and if any run in this process then either schedule a restart of
14407        // the process or kill the client waiting for it if this process has
14408        // gone bad.
14409        int NL = mLaunchingProviders.size();
14410        boolean restart = false;
14411        for (int i=0; i<NL; i++) {
14412            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14413            if (cpr.launchingApp == app) {
14414                if (!alwaysBad && !app.bad) {
14415                    restart = true;
14416                } else {
14417                    removeDyingProviderLocked(app, cpr, true);
14418                    // cpr should have been removed from mLaunchingProviders
14419                    NL = mLaunchingProviders.size();
14420                    i--;
14421                }
14422            }
14423        }
14424        return restart;
14425    }
14426
14427    // =========================================================
14428    // SERVICES
14429    // =========================================================
14430
14431    @Override
14432    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14433            int flags) {
14434        enforceNotIsolatedCaller("getServices");
14435        synchronized (this) {
14436            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14437        }
14438    }
14439
14440    @Override
14441    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14442        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14443        synchronized (this) {
14444            return mServices.getRunningServiceControlPanelLocked(name);
14445        }
14446    }
14447
14448    @Override
14449    public ComponentName startService(IApplicationThread caller, Intent service,
14450            String resolvedType, int userId) {
14451        enforceNotIsolatedCaller("startService");
14452        // Refuse possible leaked file descriptors
14453        if (service != null && service.hasFileDescriptors() == true) {
14454            throw new IllegalArgumentException("File descriptors passed in Intent");
14455        }
14456
14457        if (DEBUG_SERVICE)
14458            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14459        synchronized(this) {
14460            final int callingPid = Binder.getCallingPid();
14461            final int callingUid = Binder.getCallingUid();
14462            final long origId = Binder.clearCallingIdentity();
14463            ComponentName res = mServices.startServiceLocked(caller, service,
14464                    resolvedType, callingPid, callingUid, userId);
14465            Binder.restoreCallingIdentity(origId);
14466            return res;
14467        }
14468    }
14469
14470    ComponentName startServiceInPackage(int uid,
14471            Intent service, String resolvedType, int userId) {
14472        synchronized(this) {
14473            if (DEBUG_SERVICE)
14474                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14475            final long origId = Binder.clearCallingIdentity();
14476            ComponentName res = mServices.startServiceLocked(null, service,
14477                    resolvedType, -1, uid, userId);
14478            Binder.restoreCallingIdentity(origId);
14479            return res;
14480        }
14481    }
14482
14483    @Override
14484    public int stopService(IApplicationThread caller, Intent service,
14485            String resolvedType, int userId) {
14486        enforceNotIsolatedCaller("stopService");
14487        // Refuse possible leaked file descriptors
14488        if (service != null && service.hasFileDescriptors() == true) {
14489            throw new IllegalArgumentException("File descriptors passed in Intent");
14490        }
14491
14492        synchronized(this) {
14493            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14494        }
14495    }
14496
14497    @Override
14498    public IBinder peekService(Intent service, String resolvedType) {
14499        enforceNotIsolatedCaller("peekService");
14500        // Refuse possible leaked file descriptors
14501        if (service != null && service.hasFileDescriptors() == true) {
14502            throw new IllegalArgumentException("File descriptors passed in Intent");
14503        }
14504        synchronized(this) {
14505            return mServices.peekServiceLocked(service, resolvedType);
14506        }
14507    }
14508
14509    @Override
14510    public boolean stopServiceToken(ComponentName className, IBinder token,
14511            int startId) {
14512        synchronized(this) {
14513            return mServices.stopServiceTokenLocked(className, token, startId);
14514        }
14515    }
14516
14517    @Override
14518    public void setServiceForeground(ComponentName className, IBinder token,
14519            int id, Notification notification, boolean removeNotification) {
14520        synchronized(this) {
14521            mServices.setServiceForegroundLocked(className, token, id, notification,
14522                    removeNotification);
14523        }
14524    }
14525
14526    @Override
14527    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14528            boolean requireFull, String name, String callerPackage) {
14529        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14530                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14531    }
14532
14533    int unsafeConvertIncomingUser(int userId) {
14534        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14535                ? mCurrentUserId : userId;
14536    }
14537
14538    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14539            int allowMode, String name, String callerPackage) {
14540        final int callingUserId = UserHandle.getUserId(callingUid);
14541        if (callingUserId == userId) {
14542            return userId;
14543        }
14544
14545        // Note that we may be accessing mCurrentUserId outside of a lock...
14546        // shouldn't be a big deal, if this is being called outside
14547        // of a locked context there is intrinsically a race with
14548        // the value the caller will receive and someone else changing it.
14549        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14550        // we will switch to the calling user if access to the current user fails.
14551        int targetUserId = unsafeConvertIncomingUser(userId);
14552
14553        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14554            final boolean allow;
14555            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14556                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14557                // If the caller has this permission, they always pass go.  And collect $200.
14558                allow = true;
14559            } else if (allowMode == ALLOW_FULL_ONLY) {
14560                // We require full access, sucks to be you.
14561                allow = false;
14562            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14563                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14564                // If the caller does not have either permission, they are always doomed.
14565                allow = false;
14566            } else if (allowMode == ALLOW_NON_FULL) {
14567                // We are blanket allowing non-full access, you lucky caller!
14568                allow = true;
14569            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14570                // We may or may not allow this depending on whether the two users are
14571                // in the same profile.
14572                synchronized (mUserProfileGroupIdsSelfLocked) {
14573                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14574                            UserInfo.NO_PROFILE_GROUP_ID);
14575                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14576                            UserInfo.NO_PROFILE_GROUP_ID);
14577                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14578                            && callingProfile == targetProfile;
14579                }
14580            } else {
14581                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14582            }
14583            if (!allow) {
14584                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14585                    // In this case, they would like to just execute as their
14586                    // owner user instead of failing.
14587                    targetUserId = callingUserId;
14588                } else {
14589                    StringBuilder builder = new StringBuilder(128);
14590                    builder.append("Permission Denial: ");
14591                    builder.append(name);
14592                    if (callerPackage != null) {
14593                        builder.append(" from ");
14594                        builder.append(callerPackage);
14595                    }
14596                    builder.append(" asks to run as user ");
14597                    builder.append(userId);
14598                    builder.append(" but is calling from user ");
14599                    builder.append(UserHandle.getUserId(callingUid));
14600                    builder.append("; this requires ");
14601                    builder.append(INTERACT_ACROSS_USERS_FULL);
14602                    if (allowMode != ALLOW_FULL_ONLY) {
14603                        builder.append(" or ");
14604                        builder.append(INTERACT_ACROSS_USERS);
14605                    }
14606                    String msg = builder.toString();
14607                    Slog.w(TAG, msg);
14608                    throw new SecurityException(msg);
14609                }
14610            }
14611        }
14612        if (!allowAll && targetUserId < 0) {
14613            throw new IllegalArgumentException(
14614                    "Call does not support special user #" + targetUserId);
14615        }
14616        // Check shell permission
14617        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14618            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14619                    targetUserId)) {
14620                throw new SecurityException("Shell does not have permission to access user "
14621                        + targetUserId + "\n " + Debug.getCallers(3));
14622            }
14623        }
14624        return targetUserId;
14625    }
14626
14627    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14628            String className, int flags) {
14629        boolean result = false;
14630        // For apps that don't have pre-defined UIDs, check for permission
14631        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14632            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14633                if (ActivityManager.checkUidPermission(
14634                        INTERACT_ACROSS_USERS,
14635                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14636                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14637                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14638                            + " requests FLAG_SINGLE_USER, but app does not hold "
14639                            + INTERACT_ACROSS_USERS;
14640                    Slog.w(TAG, msg);
14641                    throw new SecurityException(msg);
14642                }
14643                // Permission passed
14644                result = true;
14645            }
14646        } else if ("system".equals(componentProcessName)) {
14647            result = true;
14648        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14649            // Phone app and persistent apps are allowed to export singleuser providers.
14650            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14651                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14652        }
14653        if (DEBUG_MU) {
14654            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14655                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14656        }
14657        return result;
14658    }
14659
14660    /**
14661     * Checks to see if the caller is in the same app as the singleton
14662     * component, or the component is in a special app. It allows special apps
14663     * to export singleton components but prevents exporting singleton
14664     * components for regular apps.
14665     */
14666    boolean isValidSingletonCall(int callingUid, int componentUid) {
14667        int componentAppId = UserHandle.getAppId(componentUid);
14668        return UserHandle.isSameApp(callingUid, componentUid)
14669                || componentAppId == Process.SYSTEM_UID
14670                || componentAppId == Process.PHONE_UID
14671                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14672                        == PackageManager.PERMISSION_GRANTED;
14673    }
14674
14675    public int bindService(IApplicationThread caller, IBinder token,
14676            Intent service, String resolvedType,
14677            IServiceConnection connection, int flags, int userId) {
14678        enforceNotIsolatedCaller("bindService");
14679
14680        // Refuse possible leaked file descriptors
14681        if (service != null && service.hasFileDescriptors() == true) {
14682            throw new IllegalArgumentException("File descriptors passed in Intent");
14683        }
14684
14685        synchronized(this) {
14686            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14687                    connection, flags, userId);
14688        }
14689    }
14690
14691    public boolean unbindService(IServiceConnection connection) {
14692        synchronized (this) {
14693            return mServices.unbindServiceLocked(connection);
14694        }
14695    }
14696
14697    public void publishService(IBinder token, Intent intent, IBinder service) {
14698        // Refuse possible leaked file descriptors
14699        if (intent != null && intent.hasFileDescriptors() == true) {
14700            throw new IllegalArgumentException("File descriptors passed in Intent");
14701        }
14702
14703        synchronized(this) {
14704            if (!(token instanceof ServiceRecord)) {
14705                throw new IllegalArgumentException("Invalid service token");
14706            }
14707            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14708        }
14709    }
14710
14711    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14712        // Refuse possible leaked file descriptors
14713        if (intent != null && intent.hasFileDescriptors() == true) {
14714            throw new IllegalArgumentException("File descriptors passed in Intent");
14715        }
14716
14717        synchronized(this) {
14718            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14719        }
14720    }
14721
14722    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14723        synchronized(this) {
14724            if (!(token instanceof ServiceRecord)) {
14725                throw new IllegalArgumentException("Invalid service token");
14726            }
14727            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14728        }
14729    }
14730
14731    // =========================================================
14732    // BACKUP AND RESTORE
14733    // =========================================================
14734
14735    // Cause the target app to be launched if necessary and its backup agent
14736    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14737    // activity manager to announce its creation.
14738    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14739        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14740        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14741
14742        synchronized(this) {
14743            // !!! TODO: currently no check here that we're already bound
14744            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14745            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14746            synchronized (stats) {
14747                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14748            }
14749
14750            // Backup agent is now in use, its package can't be stopped.
14751            try {
14752                AppGlobals.getPackageManager().setPackageStoppedState(
14753                        app.packageName, false, UserHandle.getUserId(app.uid));
14754            } catch (RemoteException e) {
14755            } catch (IllegalArgumentException e) {
14756                Slog.w(TAG, "Failed trying to unstop package "
14757                        + app.packageName + ": " + e);
14758            }
14759
14760            BackupRecord r = new BackupRecord(ss, app, backupMode);
14761            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14762                    ? new ComponentName(app.packageName, app.backupAgentName)
14763                    : new ComponentName("android", "FullBackupAgent");
14764            // startProcessLocked() returns existing proc's record if it's already running
14765            ProcessRecord proc = startProcessLocked(app.processName, app,
14766                    false, 0, "backup", hostingName, false, false, false);
14767            if (proc == null) {
14768                Slog.e(TAG, "Unable to start backup agent process " + r);
14769                return false;
14770            }
14771
14772            r.app = proc;
14773            mBackupTarget = r;
14774            mBackupAppName = app.packageName;
14775
14776            // Try not to kill the process during backup
14777            updateOomAdjLocked(proc);
14778
14779            // If the process is already attached, schedule the creation of the backup agent now.
14780            // If it is not yet live, this will be done when it attaches to the framework.
14781            if (proc.thread != null) {
14782                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14783                try {
14784                    proc.thread.scheduleCreateBackupAgent(app,
14785                            compatibilityInfoForPackageLocked(app), backupMode);
14786                } catch (RemoteException e) {
14787                    // Will time out on the backup manager side
14788                }
14789            } else {
14790                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14791            }
14792            // Invariants: at this point, the target app process exists and the application
14793            // is either already running or in the process of coming up.  mBackupTarget and
14794            // mBackupAppName describe the app, so that when it binds back to the AM we
14795            // know that it's scheduled for a backup-agent operation.
14796        }
14797
14798        return true;
14799    }
14800
14801    @Override
14802    public void clearPendingBackup() {
14803        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14804        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14805
14806        synchronized (this) {
14807            mBackupTarget = null;
14808            mBackupAppName = null;
14809        }
14810    }
14811
14812    // A backup agent has just come up
14813    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14814        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14815                + " = " + agent);
14816
14817        synchronized(this) {
14818            if (!agentPackageName.equals(mBackupAppName)) {
14819                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14820                return;
14821            }
14822        }
14823
14824        long oldIdent = Binder.clearCallingIdentity();
14825        try {
14826            IBackupManager bm = IBackupManager.Stub.asInterface(
14827                    ServiceManager.getService(Context.BACKUP_SERVICE));
14828            bm.agentConnected(agentPackageName, agent);
14829        } catch (RemoteException e) {
14830            // can't happen; the backup manager service is local
14831        } catch (Exception e) {
14832            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14833            e.printStackTrace();
14834        } finally {
14835            Binder.restoreCallingIdentity(oldIdent);
14836        }
14837    }
14838
14839    // done with this agent
14840    public void unbindBackupAgent(ApplicationInfo appInfo) {
14841        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14842        if (appInfo == null) {
14843            Slog.w(TAG, "unbind backup agent for null app");
14844            return;
14845        }
14846
14847        synchronized(this) {
14848            try {
14849                if (mBackupAppName == null) {
14850                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14851                    return;
14852                }
14853
14854                if (!mBackupAppName.equals(appInfo.packageName)) {
14855                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14856                    return;
14857                }
14858
14859                // Not backing this app up any more; reset its OOM adjustment
14860                final ProcessRecord proc = mBackupTarget.app;
14861                updateOomAdjLocked(proc);
14862
14863                // If the app crashed during backup, 'thread' will be null here
14864                if (proc.thread != null) {
14865                    try {
14866                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14867                                compatibilityInfoForPackageLocked(appInfo));
14868                    } catch (Exception e) {
14869                        Slog.e(TAG, "Exception when unbinding backup agent:");
14870                        e.printStackTrace();
14871                    }
14872                }
14873            } finally {
14874                mBackupTarget = null;
14875                mBackupAppName = null;
14876            }
14877        }
14878    }
14879    // =========================================================
14880    // BROADCASTS
14881    // =========================================================
14882
14883    private final List getStickiesLocked(String action, IntentFilter filter,
14884            List cur, int userId) {
14885        final ContentResolver resolver = mContext.getContentResolver();
14886        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14887        if (stickies == null) {
14888            return cur;
14889        }
14890        final ArrayList<Intent> list = stickies.get(action);
14891        if (list == null) {
14892            return cur;
14893        }
14894        int N = list.size();
14895        for (int i=0; i<N; i++) {
14896            Intent intent = list.get(i);
14897            if (filter.match(resolver, intent, true, TAG) >= 0) {
14898                if (cur == null) {
14899                    cur = new ArrayList<Intent>();
14900                }
14901                cur.add(intent);
14902            }
14903        }
14904        return cur;
14905    }
14906
14907    boolean isPendingBroadcastProcessLocked(int pid) {
14908        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14909                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14910    }
14911
14912    void skipPendingBroadcastLocked(int pid) {
14913            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14914            for (BroadcastQueue queue : mBroadcastQueues) {
14915                queue.skipPendingBroadcastLocked(pid);
14916            }
14917    }
14918
14919    // The app just attached; send any pending broadcasts that it should receive
14920    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14921        boolean didSomething = false;
14922        for (BroadcastQueue queue : mBroadcastQueues) {
14923            didSomething |= queue.sendPendingBroadcastsLocked(app);
14924        }
14925        return didSomething;
14926    }
14927
14928    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14929            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14930        enforceNotIsolatedCaller("registerReceiver");
14931        int callingUid;
14932        int callingPid;
14933        synchronized(this) {
14934            ProcessRecord callerApp = null;
14935            if (caller != null) {
14936                callerApp = getRecordForAppLocked(caller);
14937                if (callerApp == null) {
14938                    throw new SecurityException(
14939                            "Unable to find app for caller " + caller
14940                            + " (pid=" + Binder.getCallingPid()
14941                            + ") when registering receiver " + receiver);
14942                }
14943                if (callerApp.info.uid != Process.SYSTEM_UID &&
14944                        !callerApp.pkgList.containsKey(callerPackage) &&
14945                        !"android".equals(callerPackage)) {
14946                    throw new SecurityException("Given caller package " + callerPackage
14947                            + " is not running in process " + callerApp);
14948                }
14949                callingUid = callerApp.info.uid;
14950                callingPid = callerApp.pid;
14951            } else {
14952                callerPackage = null;
14953                callingUid = Binder.getCallingUid();
14954                callingPid = Binder.getCallingPid();
14955            }
14956
14957            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14958                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14959
14960            List allSticky = null;
14961
14962            // Look for any matching sticky broadcasts...
14963            Iterator actions = filter.actionsIterator();
14964            if (actions != null) {
14965                while (actions.hasNext()) {
14966                    String action = (String)actions.next();
14967                    allSticky = getStickiesLocked(action, filter, allSticky,
14968                            UserHandle.USER_ALL);
14969                    allSticky = getStickiesLocked(action, filter, allSticky,
14970                            UserHandle.getUserId(callingUid));
14971                }
14972            } else {
14973                allSticky = getStickiesLocked(null, filter, allSticky,
14974                        UserHandle.USER_ALL);
14975                allSticky = getStickiesLocked(null, filter, allSticky,
14976                        UserHandle.getUserId(callingUid));
14977            }
14978
14979            // The first sticky in the list is returned directly back to
14980            // the client.
14981            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14982
14983            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14984                    + ": " + sticky);
14985
14986            if (receiver == null) {
14987                return sticky;
14988            }
14989
14990            ReceiverList rl
14991                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14992            if (rl == null) {
14993                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14994                        userId, receiver);
14995                if (rl.app != null) {
14996                    rl.app.receivers.add(rl);
14997                } else {
14998                    try {
14999                        receiver.asBinder().linkToDeath(rl, 0);
15000                    } catch (RemoteException e) {
15001                        return sticky;
15002                    }
15003                    rl.linkedToDeath = true;
15004                }
15005                mRegisteredReceivers.put(receiver.asBinder(), rl);
15006            } else if (rl.uid != callingUid) {
15007                throw new IllegalArgumentException(
15008                        "Receiver requested to register for uid " + callingUid
15009                        + " was previously registered for uid " + rl.uid);
15010            } else if (rl.pid != callingPid) {
15011                throw new IllegalArgumentException(
15012                        "Receiver requested to register for pid " + callingPid
15013                        + " was previously registered for pid " + rl.pid);
15014            } else if (rl.userId != userId) {
15015                throw new IllegalArgumentException(
15016                        "Receiver requested to register for user " + userId
15017                        + " was previously registered for user " + rl.userId);
15018            }
15019            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15020                    permission, callingUid, userId);
15021            rl.add(bf);
15022            if (!bf.debugCheck()) {
15023                Slog.w(TAG, "==> For Dynamic broadast");
15024            }
15025            mReceiverResolver.addFilter(bf);
15026
15027            // Enqueue broadcasts for all existing stickies that match
15028            // this filter.
15029            if (allSticky != null) {
15030                ArrayList receivers = new ArrayList();
15031                receivers.add(bf);
15032
15033                int N = allSticky.size();
15034                for (int i=0; i<N; i++) {
15035                    Intent intent = (Intent)allSticky.get(i);
15036                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15037                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15038                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15039                            null, null, false, true, true, -1);
15040                    queue.enqueueParallelBroadcastLocked(r);
15041                    queue.scheduleBroadcastsLocked();
15042                }
15043            }
15044
15045            return sticky;
15046        }
15047    }
15048
15049    public void unregisterReceiver(IIntentReceiver receiver) {
15050        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15051
15052        final long origId = Binder.clearCallingIdentity();
15053        try {
15054            boolean doTrim = false;
15055
15056            synchronized(this) {
15057                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15058                if (rl != null) {
15059                    if (rl.curBroadcast != null) {
15060                        BroadcastRecord r = rl.curBroadcast;
15061                        final boolean doNext = finishReceiverLocked(
15062                                receiver.asBinder(), r.resultCode, r.resultData,
15063                                r.resultExtras, r.resultAbort);
15064                        if (doNext) {
15065                            doTrim = true;
15066                            r.queue.processNextBroadcast(false);
15067                        }
15068                    }
15069
15070                    if (rl.app != null) {
15071                        rl.app.receivers.remove(rl);
15072                    }
15073                    removeReceiverLocked(rl);
15074                    if (rl.linkedToDeath) {
15075                        rl.linkedToDeath = false;
15076                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15077                    }
15078                }
15079            }
15080
15081            // If we actually concluded any broadcasts, we might now be able
15082            // to trim the recipients' apps from our working set
15083            if (doTrim) {
15084                trimApplications();
15085                return;
15086            }
15087
15088        } finally {
15089            Binder.restoreCallingIdentity(origId);
15090        }
15091    }
15092
15093    void removeReceiverLocked(ReceiverList rl) {
15094        mRegisteredReceivers.remove(rl.receiver.asBinder());
15095        int N = rl.size();
15096        for (int i=0; i<N; i++) {
15097            mReceiverResolver.removeFilter(rl.get(i));
15098        }
15099    }
15100
15101    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15102        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15103            ProcessRecord r = mLruProcesses.get(i);
15104            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15105                try {
15106                    r.thread.dispatchPackageBroadcast(cmd, packages);
15107                } catch (RemoteException ex) {
15108                }
15109            }
15110        }
15111    }
15112
15113    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15114            int callingUid, int[] users) {
15115        List<ResolveInfo> receivers = null;
15116        try {
15117            HashSet<ComponentName> singleUserReceivers = null;
15118            boolean scannedFirstReceivers = false;
15119            for (int user : users) {
15120                // Skip users that have Shell restrictions
15121                if (callingUid == Process.SHELL_UID
15122                        && getUserManagerLocked().hasUserRestriction(
15123                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15124                    continue;
15125                }
15126                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15127                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15128                if (user != 0 && newReceivers != null) {
15129                    // If this is not the primary user, we need to check for
15130                    // any receivers that should be filtered out.
15131                    for (int i=0; i<newReceivers.size(); i++) {
15132                        ResolveInfo ri = newReceivers.get(i);
15133                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15134                            newReceivers.remove(i);
15135                            i--;
15136                        }
15137                    }
15138                }
15139                if (newReceivers != null && newReceivers.size() == 0) {
15140                    newReceivers = null;
15141                }
15142                if (receivers == null) {
15143                    receivers = newReceivers;
15144                } else if (newReceivers != null) {
15145                    // We need to concatenate the additional receivers
15146                    // found with what we have do far.  This would be easy,
15147                    // but we also need to de-dup any receivers that are
15148                    // singleUser.
15149                    if (!scannedFirstReceivers) {
15150                        // Collect any single user receivers we had already retrieved.
15151                        scannedFirstReceivers = true;
15152                        for (int i=0; i<receivers.size(); i++) {
15153                            ResolveInfo ri = receivers.get(i);
15154                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15155                                ComponentName cn = new ComponentName(
15156                                        ri.activityInfo.packageName, ri.activityInfo.name);
15157                                if (singleUserReceivers == null) {
15158                                    singleUserReceivers = new HashSet<ComponentName>();
15159                                }
15160                                singleUserReceivers.add(cn);
15161                            }
15162                        }
15163                    }
15164                    // Add the new results to the existing results, tracking
15165                    // and de-dupping single user receivers.
15166                    for (int i=0; i<newReceivers.size(); i++) {
15167                        ResolveInfo ri = newReceivers.get(i);
15168                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15169                            ComponentName cn = new ComponentName(
15170                                    ri.activityInfo.packageName, ri.activityInfo.name);
15171                            if (singleUserReceivers == null) {
15172                                singleUserReceivers = new HashSet<ComponentName>();
15173                            }
15174                            if (!singleUserReceivers.contains(cn)) {
15175                                singleUserReceivers.add(cn);
15176                                receivers.add(ri);
15177                            }
15178                        } else {
15179                            receivers.add(ri);
15180                        }
15181                    }
15182                }
15183            }
15184        } catch (RemoteException ex) {
15185            // pm is in same process, this will never happen.
15186        }
15187        return receivers;
15188    }
15189
15190    private final int broadcastIntentLocked(ProcessRecord callerApp,
15191            String callerPackage, Intent intent, String resolvedType,
15192            IIntentReceiver resultTo, int resultCode, String resultData,
15193            Bundle map, String requiredPermission, int appOp,
15194            boolean ordered, boolean sticky, int callingPid, int callingUid,
15195            int userId) {
15196        intent = new Intent(intent);
15197
15198        // By default broadcasts do not go to stopped apps.
15199        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15200
15201        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15202            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15203            + " ordered=" + ordered + " userid=" + userId);
15204        if ((resultTo != null) && !ordered) {
15205            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15206        }
15207
15208        userId = handleIncomingUser(callingPid, callingUid, userId,
15209                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15210
15211        // Make sure that the user who is receiving this broadcast is started.
15212        // If not, we will just skip it.
15213
15214        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15215            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15216                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15217                Slog.w(TAG, "Skipping broadcast of " + intent
15218                        + ": user " + userId + " is stopped");
15219                return ActivityManager.BROADCAST_SUCCESS;
15220            }
15221        }
15222
15223        /*
15224         * Prevent non-system code (defined here to be non-persistent
15225         * processes) from sending protected broadcasts.
15226         */
15227        int callingAppId = UserHandle.getAppId(callingUid);
15228        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15229            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15230            || callingAppId == Process.NFC_UID || callingUid == 0) {
15231            // Always okay.
15232        } else if (callerApp == null || !callerApp.persistent) {
15233            try {
15234                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15235                        intent.getAction())) {
15236                    String msg = "Permission Denial: not allowed to send broadcast "
15237                            + intent.getAction() + " from pid="
15238                            + callingPid + ", uid=" + callingUid;
15239                    Slog.w(TAG, msg);
15240                    throw new SecurityException(msg);
15241                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15242                    // Special case for compatibility: we don't want apps to send this,
15243                    // but historically it has not been protected and apps may be using it
15244                    // to poke their own app widget.  So, instead of making it protected,
15245                    // just limit it to the caller.
15246                    if (callerApp == null) {
15247                        String msg = "Permission Denial: not allowed to send broadcast "
15248                                + intent.getAction() + " from unknown caller.";
15249                        Slog.w(TAG, msg);
15250                        throw new SecurityException(msg);
15251                    } else if (intent.getComponent() != null) {
15252                        // They are good enough to send to an explicit component...  verify
15253                        // it is being sent to the calling app.
15254                        if (!intent.getComponent().getPackageName().equals(
15255                                callerApp.info.packageName)) {
15256                            String msg = "Permission Denial: not allowed to send broadcast "
15257                                    + intent.getAction() + " to "
15258                                    + intent.getComponent().getPackageName() + " from "
15259                                    + callerApp.info.packageName;
15260                            Slog.w(TAG, msg);
15261                            throw new SecurityException(msg);
15262                        }
15263                    } else {
15264                        // Limit broadcast to their own package.
15265                        intent.setPackage(callerApp.info.packageName);
15266                    }
15267                }
15268            } catch (RemoteException e) {
15269                Slog.w(TAG, "Remote exception", e);
15270                return ActivityManager.BROADCAST_SUCCESS;
15271            }
15272        }
15273
15274        // Handle special intents: if this broadcast is from the package
15275        // manager about a package being removed, we need to remove all of
15276        // its activities from the history stack.
15277        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15278                intent.getAction());
15279        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15280                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15281                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15282                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15283                || uidRemoved) {
15284            if (checkComponentPermission(
15285                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15286                    callingPid, callingUid, -1, true)
15287                    == PackageManager.PERMISSION_GRANTED) {
15288                if (uidRemoved) {
15289                    final Bundle intentExtras = intent.getExtras();
15290                    final int uid = intentExtras != null
15291                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15292                    if (uid >= 0) {
15293                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15294                        synchronized (bs) {
15295                            bs.removeUidStatsLocked(uid);
15296                        }
15297                        mAppOpsService.uidRemoved(uid);
15298                    }
15299                } else {
15300                    // If resources are unavailable just force stop all
15301                    // those packages and flush the attribute cache as well.
15302                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15303                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15304                        if (list != null && (list.length > 0)) {
15305                            for (String pkg : list) {
15306                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15307                                        "storage unmount");
15308                            }
15309                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15310                            sendPackageBroadcastLocked(
15311                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15312                        }
15313                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15314                            intent.getAction())) {
15315                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15316                    } else {
15317                        Uri data = intent.getData();
15318                        String ssp;
15319                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15320                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15321                                    intent.getAction());
15322                            boolean fullUninstall = removed &&
15323                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15324                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15325                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15326                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15327                                        false, fullUninstall, userId,
15328                                        removed ? "pkg removed" : "pkg changed");
15329                            }
15330                            if (removed) {
15331                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15332                                        new String[] {ssp}, userId);
15333                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15334                                    mAppOpsService.packageRemoved(
15335                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15336
15337                                    // Remove all permissions granted from/to this package
15338                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15339                                }
15340                            }
15341                        }
15342                    }
15343                }
15344            } else {
15345                String msg = "Permission Denial: " + intent.getAction()
15346                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15347                        + ", uid=" + callingUid + ")"
15348                        + " requires "
15349                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15350                Slog.w(TAG, msg);
15351                throw new SecurityException(msg);
15352            }
15353
15354        // Special case for adding a package: by default turn on compatibility
15355        // mode.
15356        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15357            Uri data = intent.getData();
15358            String ssp;
15359            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15360                mCompatModePackages.handlePackageAddedLocked(ssp,
15361                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15362            }
15363        }
15364
15365        /*
15366         * If this is the time zone changed action, queue up a message that will reset the timezone
15367         * of all currently running processes. This message will get queued up before the broadcast
15368         * happens.
15369         */
15370        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15371            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15372        }
15373
15374        /*
15375         * If the user set the time, let all running processes know.
15376         */
15377        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15378            final int is24Hour = intent.getBooleanExtra(
15379                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15380            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15381            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15382            synchronized (stats) {
15383                stats.noteCurrentTimeChangedLocked();
15384            }
15385        }
15386
15387        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15388            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15389        }
15390
15391        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15392            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15393            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15394        }
15395
15396        // Add to the sticky list if requested.
15397        if (sticky) {
15398            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15399                    callingPid, callingUid)
15400                    != PackageManager.PERMISSION_GRANTED) {
15401                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15402                        + callingPid + ", uid=" + callingUid
15403                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15404                Slog.w(TAG, msg);
15405                throw new SecurityException(msg);
15406            }
15407            if (requiredPermission != null) {
15408                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15409                        + " and enforce permission " + requiredPermission);
15410                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15411            }
15412            if (intent.getComponent() != null) {
15413                throw new SecurityException(
15414                        "Sticky broadcasts can't target a specific component");
15415            }
15416            // We use userId directly here, since the "all" target is maintained
15417            // as a separate set of sticky broadcasts.
15418            if (userId != UserHandle.USER_ALL) {
15419                // But first, if this is not a broadcast to all users, then
15420                // make sure it doesn't conflict with an existing broadcast to
15421                // all users.
15422                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15423                        UserHandle.USER_ALL);
15424                if (stickies != null) {
15425                    ArrayList<Intent> list = stickies.get(intent.getAction());
15426                    if (list != null) {
15427                        int N = list.size();
15428                        int i;
15429                        for (i=0; i<N; i++) {
15430                            if (intent.filterEquals(list.get(i))) {
15431                                throw new IllegalArgumentException(
15432                                        "Sticky broadcast " + intent + " for user "
15433                                        + userId + " conflicts with existing global broadcast");
15434                            }
15435                        }
15436                    }
15437                }
15438            }
15439            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15440            if (stickies == null) {
15441                stickies = new ArrayMap<String, ArrayList<Intent>>();
15442                mStickyBroadcasts.put(userId, stickies);
15443            }
15444            ArrayList<Intent> list = stickies.get(intent.getAction());
15445            if (list == null) {
15446                list = new ArrayList<Intent>();
15447                stickies.put(intent.getAction(), list);
15448            }
15449            int N = list.size();
15450            int i;
15451            for (i=0; i<N; i++) {
15452                if (intent.filterEquals(list.get(i))) {
15453                    // This sticky already exists, replace it.
15454                    list.set(i, new Intent(intent));
15455                    break;
15456                }
15457            }
15458            if (i >= N) {
15459                list.add(new Intent(intent));
15460            }
15461        }
15462
15463        int[] users;
15464        if (userId == UserHandle.USER_ALL) {
15465            // Caller wants broadcast to go to all started users.
15466            users = mStartedUserArray;
15467        } else {
15468            // Caller wants broadcast to go to one specific user.
15469            users = new int[] {userId};
15470        }
15471
15472        // Figure out who all will receive this broadcast.
15473        List receivers = null;
15474        List<BroadcastFilter> registeredReceivers = null;
15475        // Need to resolve the intent to interested receivers...
15476        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15477                 == 0) {
15478            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15479        }
15480        if (intent.getComponent() == null) {
15481            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15482                // Query one target user at a time, excluding shell-restricted users
15483                UserManagerService ums = getUserManagerLocked();
15484                for (int i = 0; i < users.length; i++) {
15485                    if (ums.hasUserRestriction(
15486                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15487                        continue;
15488                    }
15489                    List<BroadcastFilter> registeredReceiversForUser =
15490                            mReceiverResolver.queryIntent(intent,
15491                                    resolvedType, false, users[i]);
15492                    if (registeredReceivers == null) {
15493                        registeredReceivers = registeredReceiversForUser;
15494                    } else if (registeredReceiversForUser != null) {
15495                        registeredReceivers.addAll(registeredReceiversForUser);
15496                    }
15497                }
15498            } else {
15499                registeredReceivers = mReceiverResolver.queryIntent(intent,
15500                        resolvedType, false, userId);
15501            }
15502        }
15503
15504        final boolean replacePending =
15505                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15506
15507        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15508                + " replacePending=" + replacePending);
15509
15510        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15511        if (!ordered && NR > 0) {
15512            // If we are not serializing this broadcast, then send the
15513            // registered receivers separately so they don't wait for the
15514            // components to be launched.
15515            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15516            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15517                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15518                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15519                    ordered, sticky, false, userId);
15520            if (DEBUG_BROADCAST) Slog.v(
15521                    TAG, "Enqueueing parallel broadcast " + r);
15522            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15523            if (!replaced) {
15524                queue.enqueueParallelBroadcastLocked(r);
15525                queue.scheduleBroadcastsLocked();
15526            }
15527            registeredReceivers = null;
15528            NR = 0;
15529        }
15530
15531        // Merge into one list.
15532        int ir = 0;
15533        if (receivers != null) {
15534            // A special case for PACKAGE_ADDED: do not allow the package
15535            // being added to see this broadcast.  This prevents them from
15536            // using this as a back door to get run as soon as they are
15537            // installed.  Maybe in the future we want to have a special install
15538            // broadcast or such for apps, but we'd like to deliberately make
15539            // this decision.
15540            String skipPackages[] = null;
15541            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15542                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15543                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15544                Uri data = intent.getData();
15545                if (data != null) {
15546                    String pkgName = data.getSchemeSpecificPart();
15547                    if (pkgName != null) {
15548                        skipPackages = new String[] { pkgName };
15549                    }
15550                }
15551            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15552                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15553            }
15554            if (skipPackages != null && (skipPackages.length > 0)) {
15555                for (String skipPackage : skipPackages) {
15556                    if (skipPackage != null) {
15557                        int NT = receivers.size();
15558                        for (int it=0; it<NT; it++) {
15559                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15560                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15561                                receivers.remove(it);
15562                                it--;
15563                                NT--;
15564                            }
15565                        }
15566                    }
15567                }
15568            }
15569
15570            int NT = receivers != null ? receivers.size() : 0;
15571            int it = 0;
15572            ResolveInfo curt = null;
15573            BroadcastFilter curr = null;
15574            while (it < NT && ir < NR) {
15575                if (curt == null) {
15576                    curt = (ResolveInfo)receivers.get(it);
15577                }
15578                if (curr == null) {
15579                    curr = registeredReceivers.get(ir);
15580                }
15581                if (curr.getPriority() >= curt.priority) {
15582                    // Insert this broadcast record into the final list.
15583                    receivers.add(it, curr);
15584                    ir++;
15585                    curr = null;
15586                    it++;
15587                    NT++;
15588                } else {
15589                    // Skip to the next ResolveInfo in the final list.
15590                    it++;
15591                    curt = null;
15592                }
15593            }
15594        }
15595        while (ir < NR) {
15596            if (receivers == null) {
15597                receivers = new ArrayList();
15598            }
15599            receivers.add(registeredReceivers.get(ir));
15600            ir++;
15601        }
15602
15603        if ((receivers != null && receivers.size() > 0)
15604                || resultTo != null) {
15605            BroadcastQueue queue = broadcastQueueForIntent(intent);
15606            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15607                    callerPackage, callingPid, callingUid, resolvedType,
15608                    requiredPermission, appOp, receivers, resultTo, resultCode,
15609                    resultData, map, ordered, sticky, false, userId);
15610            if (DEBUG_BROADCAST) Slog.v(
15611                    TAG, "Enqueueing ordered broadcast " + r
15612                    + ": prev had " + queue.mOrderedBroadcasts.size());
15613            if (DEBUG_BROADCAST) {
15614                int seq = r.intent.getIntExtra("seq", -1);
15615                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15616            }
15617            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15618            if (!replaced) {
15619                queue.enqueueOrderedBroadcastLocked(r);
15620                queue.scheduleBroadcastsLocked();
15621            }
15622        }
15623
15624        return ActivityManager.BROADCAST_SUCCESS;
15625    }
15626
15627    final Intent verifyBroadcastLocked(Intent intent) {
15628        // Refuse possible leaked file descriptors
15629        if (intent != null && intent.hasFileDescriptors() == true) {
15630            throw new IllegalArgumentException("File descriptors passed in Intent");
15631        }
15632
15633        int flags = intent.getFlags();
15634
15635        if (!mProcessesReady) {
15636            // if the caller really truly claims to know what they're doing, go
15637            // ahead and allow the broadcast without launching any receivers
15638            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15639                intent = new Intent(intent);
15640                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15641            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15642                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15643                        + " before boot completion");
15644                throw new IllegalStateException("Cannot broadcast before boot completed");
15645            }
15646        }
15647
15648        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15649            throw new IllegalArgumentException(
15650                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15651        }
15652
15653        return intent;
15654    }
15655
15656    public final int broadcastIntent(IApplicationThread caller,
15657            Intent intent, String resolvedType, IIntentReceiver resultTo,
15658            int resultCode, String resultData, Bundle map,
15659            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15660        enforceNotIsolatedCaller("broadcastIntent");
15661        synchronized(this) {
15662            intent = verifyBroadcastLocked(intent);
15663
15664            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15665            final int callingPid = Binder.getCallingPid();
15666            final int callingUid = Binder.getCallingUid();
15667            final long origId = Binder.clearCallingIdentity();
15668            int res = broadcastIntentLocked(callerApp,
15669                    callerApp != null ? callerApp.info.packageName : null,
15670                    intent, resolvedType, resultTo,
15671                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15672                    callingPid, callingUid, userId);
15673            Binder.restoreCallingIdentity(origId);
15674            return res;
15675        }
15676    }
15677
15678    int broadcastIntentInPackage(String packageName, int uid,
15679            Intent intent, String resolvedType, IIntentReceiver resultTo,
15680            int resultCode, String resultData, Bundle map,
15681            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15682        synchronized(this) {
15683            intent = verifyBroadcastLocked(intent);
15684
15685            final long origId = Binder.clearCallingIdentity();
15686            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15687                    resultTo, resultCode, resultData, map, requiredPermission,
15688                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15689            Binder.restoreCallingIdentity(origId);
15690            return res;
15691        }
15692    }
15693
15694    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15695        // Refuse possible leaked file descriptors
15696        if (intent != null && intent.hasFileDescriptors() == true) {
15697            throw new IllegalArgumentException("File descriptors passed in Intent");
15698        }
15699
15700        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15701                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15702
15703        synchronized(this) {
15704            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15705                    != PackageManager.PERMISSION_GRANTED) {
15706                String msg = "Permission Denial: unbroadcastIntent() from pid="
15707                        + Binder.getCallingPid()
15708                        + ", uid=" + Binder.getCallingUid()
15709                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15710                Slog.w(TAG, msg);
15711                throw new SecurityException(msg);
15712            }
15713            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15714            if (stickies != null) {
15715                ArrayList<Intent> list = stickies.get(intent.getAction());
15716                if (list != null) {
15717                    int N = list.size();
15718                    int i;
15719                    for (i=0; i<N; i++) {
15720                        if (intent.filterEquals(list.get(i))) {
15721                            list.remove(i);
15722                            break;
15723                        }
15724                    }
15725                    if (list.size() <= 0) {
15726                        stickies.remove(intent.getAction());
15727                    }
15728                }
15729                if (stickies.size() <= 0) {
15730                    mStickyBroadcasts.remove(userId);
15731                }
15732            }
15733        }
15734    }
15735
15736    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15737            String resultData, Bundle resultExtras, boolean resultAbort) {
15738        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15739        if (r == null) {
15740            Slog.w(TAG, "finishReceiver called but not found on queue");
15741            return false;
15742        }
15743
15744        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15745    }
15746
15747    void backgroundServicesFinishedLocked(int userId) {
15748        for (BroadcastQueue queue : mBroadcastQueues) {
15749            queue.backgroundServicesFinishedLocked(userId);
15750        }
15751    }
15752
15753    public void finishReceiver(IBinder who, int resultCode, String resultData,
15754            Bundle resultExtras, boolean resultAbort) {
15755        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15756
15757        // Refuse possible leaked file descriptors
15758        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15759            throw new IllegalArgumentException("File descriptors passed in Bundle");
15760        }
15761
15762        final long origId = Binder.clearCallingIdentity();
15763        try {
15764            boolean doNext = false;
15765            BroadcastRecord r;
15766
15767            synchronized(this) {
15768                r = broadcastRecordForReceiverLocked(who);
15769                if (r != null) {
15770                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15771                        resultData, resultExtras, resultAbort, true);
15772                }
15773            }
15774
15775            if (doNext) {
15776                r.queue.processNextBroadcast(false);
15777            }
15778            trimApplications();
15779        } finally {
15780            Binder.restoreCallingIdentity(origId);
15781        }
15782    }
15783
15784    // =========================================================
15785    // INSTRUMENTATION
15786    // =========================================================
15787
15788    public boolean startInstrumentation(ComponentName className,
15789            String profileFile, int flags, Bundle arguments,
15790            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15791            int userId, String abiOverride) {
15792        enforceNotIsolatedCaller("startInstrumentation");
15793        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15794                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15795        // Refuse possible leaked file descriptors
15796        if (arguments != null && arguments.hasFileDescriptors()) {
15797            throw new IllegalArgumentException("File descriptors passed in Bundle");
15798        }
15799
15800        synchronized(this) {
15801            InstrumentationInfo ii = null;
15802            ApplicationInfo ai = null;
15803            try {
15804                ii = mContext.getPackageManager().getInstrumentationInfo(
15805                    className, STOCK_PM_FLAGS);
15806                ai = AppGlobals.getPackageManager().getApplicationInfo(
15807                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15808            } catch (PackageManager.NameNotFoundException e) {
15809            } catch (RemoteException e) {
15810            }
15811            if (ii == null) {
15812                reportStartInstrumentationFailure(watcher, className,
15813                        "Unable to find instrumentation info for: " + className);
15814                return false;
15815            }
15816            if (ai == null) {
15817                reportStartInstrumentationFailure(watcher, className,
15818                        "Unable to find instrumentation target package: " + ii.targetPackage);
15819                return false;
15820            }
15821
15822            int match = mContext.getPackageManager().checkSignatures(
15823                    ii.targetPackage, ii.packageName);
15824            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15825                String msg = "Permission Denial: starting instrumentation "
15826                        + className + " from pid="
15827                        + Binder.getCallingPid()
15828                        + ", uid=" + Binder.getCallingPid()
15829                        + " not allowed because package " + ii.packageName
15830                        + " does not have a signature matching the target "
15831                        + ii.targetPackage;
15832                reportStartInstrumentationFailure(watcher, className, msg);
15833                throw new SecurityException(msg);
15834            }
15835
15836            final long origId = Binder.clearCallingIdentity();
15837            // Instrumentation can kill and relaunch even persistent processes
15838            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15839                    "start instr");
15840            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15841            app.instrumentationClass = className;
15842            app.instrumentationInfo = ai;
15843            app.instrumentationProfileFile = profileFile;
15844            app.instrumentationArguments = arguments;
15845            app.instrumentationWatcher = watcher;
15846            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15847            app.instrumentationResultClass = className;
15848            Binder.restoreCallingIdentity(origId);
15849        }
15850
15851        return true;
15852    }
15853
15854    /**
15855     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15856     * error to the logs, but if somebody is watching, send the report there too.  This enables
15857     * the "am" command to report errors with more information.
15858     *
15859     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15860     * @param cn The component name of the instrumentation.
15861     * @param report The error report.
15862     */
15863    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15864            ComponentName cn, String report) {
15865        Slog.w(TAG, report);
15866        try {
15867            if (watcher != null) {
15868                Bundle results = new Bundle();
15869                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15870                results.putString("Error", report);
15871                watcher.instrumentationStatus(cn, -1, results);
15872            }
15873        } catch (RemoteException e) {
15874            Slog.w(TAG, e);
15875        }
15876    }
15877
15878    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15879        if (app.instrumentationWatcher != null) {
15880            try {
15881                // NOTE:  IInstrumentationWatcher *must* be oneway here
15882                app.instrumentationWatcher.instrumentationFinished(
15883                    app.instrumentationClass,
15884                    resultCode,
15885                    results);
15886            } catch (RemoteException e) {
15887            }
15888        }
15889        if (app.instrumentationUiAutomationConnection != null) {
15890            try {
15891                app.instrumentationUiAutomationConnection.shutdown();
15892            } catch (RemoteException re) {
15893                /* ignore */
15894            }
15895            // Only a UiAutomation can set this flag and now that
15896            // it is finished we make sure it is reset to its default.
15897            mUserIsMonkey = false;
15898        }
15899        app.instrumentationWatcher = null;
15900        app.instrumentationUiAutomationConnection = null;
15901        app.instrumentationClass = null;
15902        app.instrumentationInfo = null;
15903        app.instrumentationProfileFile = null;
15904        app.instrumentationArguments = null;
15905
15906        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15907                "finished inst");
15908    }
15909
15910    public void finishInstrumentation(IApplicationThread target,
15911            int resultCode, Bundle results) {
15912        int userId = UserHandle.getCallingUserId();
15913        // Refuse possible leaked file descriptors
15914        if (results != null && results.hasFileDescriptors()) {
15915            throw new IllegalArgumentException("File descriptors passed in Intent");
15916        }
15917
15918        synchronized(this) {
15919            ProcessRecord app = getRecordForAppLocked(target);
15920            if (app == null) {
15921                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15922                return;
15923            }
15924            final long origId = Binder.clearCallingIdentity();
15925            finishInstrumentationLocked(app, resultCode, results);
15926            Binder.restoreCallingIdentity(origId);
15927        }
15928    }
15929
15930    // =========================================================
15931    // CONFIGURATION
15932    // =========================================================
15933
15934    public ConfigurationInfo getDeviceConfigurationInfo() {
15935        ConfigurationInfo config = new ConfigurationInfo();
15936        synchronized (this) {
15937            config.reqTouchScreen = mConfiguration.touchscreen;
15938            config.reqKeyboardType = mConfiguration.keyboard;
15939            config.reqNavigation = mConfiguration.navigation;
15940            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15941                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15942                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15943            }
15944            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15945                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15946                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15947            }
15948            config.reqGlEsVersion = GL_ES_VERSION;
15949        }
15950        return config;
15951    }
15952
15953    ActivityStack getFocusedStack() {
15954        return mStackSupervisor.getFocusedStack();
15955    }
15956
15957    public Configuration getConfiguration() {
15958        Configuration ci;
15959        synchronized(this) {
15960            ci = new Configuration(mConfiguration);
15961        }
15962        return ci;
15963    }
15964
15965    public void updatePersistentConfiguration(Configuration values) {
15966        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15967                "updateConfiguration()");
15968        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15969                "updateConfiguration()");
15970        if (values == null) {
15971            throw new NullPointerException("Configuration must not be null");
15972        }
15973
15974        synchronized(this) {
15975            final long origId = Binder.clearCallingIdentity();
15976            updateConfigurationLocked(values, null, true, false);
15977            Binder.restoreCallingIdentity(origId);
15978        }
15979    }
15980
15981    public void updateConfiguration(Configuration values) {
15982        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15983                "updateConfiguration()");
15984
15985        synchronized(this) {
15986            if (values == null && mWindowManager != null) {
15987                // sentinel: fetch the current configuration from the window manager
15988                values = mWindowManager.computeNewConfiguration();
15989            }
15990
15991            if (mWindowManager != null) {
15992                mProcessList.applyDisplaySize(mWindowManager);
15993            }
15994
15995            final long origId = Binder.clearCallingIdentity();
15996            if (values != null) {
15997                Settings.System.clearConfiguration(values);
15998            }
15999            updateConfigurationLocked(values, null, false, false);
16000            Binder.restoreCallingIdentity(origId);
16001        }
16002    }
16003
16004    /**
16005     * Do either or both things: (1) change the current configuration, and (2)
16006     * make sure the given activity is running with the (now) current
16007     * configuration.  Returns true if the activity has been left running, or
16008     * false if <var>starting</var> is being destroyed to match the new
16009     * configuration.
16010     * @param persistent TODO
16011     */
16012    boolean updateConfigurationLocked(Configuration values,
16013            ActivityRecord starting, boolean persistent, boolean initLocale) {
16014        int changes = 0;
16015
16016        if (values != null) {
16017            Configuration newConfig = new Configuration(mConfiguration);
16018            changes = newConfig.updateFrom(values);
16019            if (changes != 0) {
16020                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16021                    Slog.i(TAG, "Updating configuration to: " + values);
16022                }
16023
16024                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16025
16026                if (values.locale != null && !initLocale) {
16027                    saveLocaleLocked(values.locale,
16028                                     !values.locale.equals(mConfiguration.locale),
16029                                     values.userSetLocale);
16030                }
16031
16032                mConfigurationSeq++;
16033                if (mConfigurationSeq <= 0) {
16034                    mConfigurationSeq = 1;
16035                }
16036                newConfig.seq = mConfigurationSeq;
16037                mConfiguration = newConfig;
16038                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16039                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16040                //mUsageStatsService.noteStartConfig(newConfig);
16041
16042                final Configuration configCopy = new Configuration(mConfiguration);
16043
16044                // TODO: If our config changes, should we auto dismiss any currently
16045                // showing dialogs?
16046                mShowDialogs = shouldShowDialogs(newConfig);
16047
16048                AttributeCache ac = AttributeCache.instance();
16049                if (ac != null) {
16050                    ac.updateConfiguration(configCopy);
16051                }
16052
16053                // Make sure all resources in our process are updated
16054                // right now, so that anyone who is going to retrieve
16055                // resource values after we return will be sure to get
16056                // the new ones.  This is especially important during
16057                // boot, where the first config change needs to guarantee
16058                // all resources have that config before following boot
16059                // code is executed.
16060                mSystemThread.applyConfigurationToResources(configCopy);
16061
16062                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16063                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16064                    msg.obj = new Configuration(configCopy);
16065                    mHandler.sendMessage(msg);
16066                }
16067
16068                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16069                    ProcessRecord app = mLruProcesses.get(i);
16070                    try {
16071                        if (app.thread != null) {
16072                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16073                                    + app.processName + " new config " + mConfiguration);
16074                            app.thread.scheduleConfigurationChanged(configCopy);
16075                        }
16076                    } catch (Exception e) {
16077                    }
16078                }
16079                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16080                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16081                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16082                        | Intent.FLAG_RECEIVER_FOREGROUND);
16083                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16084                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16085                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16086                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16087                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16088                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16089                    broadcastIntentLocked(null, null, intent,
16090                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16091                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16092                }
16093            }
16094        }
16095
16096        boolean kept = true;
16097        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16098        // mainStack is null during startup.
16099        if (mainStack != null) {
16100            if (changes != 0 && starting == null) {
16101                // If the configuration changed, and the caller is not already
16102                // in the process of starting an activity, then find the top
16103                // activity to check if its configuration needs to change.
16104                starting = mainStack.topRunningActivityLocked(null);
16105            }
16106
16107            if (starting != null) {
16108                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16109                // And we need to make sure at this point that all other activities
16110                // are made visible with the correct configuration.
16111                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16112            }
16113        }
16114
16115        if (values != null && mWindowManager != null) {
16116            mWindowManager.setNewConfiguration(mConfiguration);
16117        }
16118
16119        return kept;
16120    }
16121
16122    /**
16123     * Decide based on the configuration whether we should shouw the ANR,
16124     * crash, etc dialogs.  The idea is that if there is no affordnace to
16125     * press the on-screen buttons, we shouldn't show the dialog.
16126     *
16127     * A thought: SystemUI might also want to get told about this, the Power
16128     * dialog / global actions also might want different behaviors.
16129     */
16130    private static final boolean shouldShowDialogs(Configuration config) {
16131        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16132                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16133    }
16134
16135    /**
16136     * Save the locale.  You must be inside a synchronized (this) block.
16137     */
16138    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16139        if(isDiff) {
16140            SystemProperties.set("user.language", l.getLanguage());
16141            SystemProperties.set("user.region", l.getCountry());
16142        }
16143
16144        if(isPersist) {
16145            SystemProperties.set("persist.sys.language", l.getLanguage());
16146            SystemProperties.set("persist.sys.country", l.getCountry());
16147            SystemProperties.set("persist.sys.localevar", l.getVariant());
16148        }
16149    }
16150
16151    @Override
16152    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16153        synchronized (this) {
16154            ActivityRecord srec = ActivityRecord.forToken(token);
16155            if (srec.task != null && srec.task.stack != null) {
16156                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16157            }
16158        }
16159        return false;
16160    }
16161
16162    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16163            Intent resultData) {
16164
16165        synchronized (this) {
16166            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16167            if (stack != null) {
16168                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16169            }
16170            return false;
16171        }
16172    }
16173
16174    public int getLaunchedFromUid(IBinder activityToken) {
16175        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16176        if (srec == null) {
16177            return -1;
16178        }
16179        return srec.launchedFromUid;
16180    }
16181
16182    public String getLaunchedFromPackage(IBinder activityToken) {
16183        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16184        if (srec == null) {
16185            return null;
16186        }
16187        return srec.launchedFromPackage;
16188    }
16189
16190    // =========================================================
16191    // LIFETIME MANAGEMENT
16192    // =========================================================
16193
16194    // Returns which broadcast queue the app is the current [or imminent] receiver
16195    // on, or 'null' if the app is not an active broadcast recipient.
16196    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16197        BroadcastRecord r = app.curReceiver;
16198        if (r != null) {
16199            return r.queue;
16200        }
16201
16202        // It's not the current receiver, but it might be starting up to become one
16203        synchronized (this) {
16204            for (BroadcastQueue queue : mBroadcastQueues) {
16205                r = queue.mPendingBroadcast;
16206                if (r != null && r.curApp == app) {
16207                    // found it; report which queue it's in
16208                    return queue;
16209                }
16210            }
16211        }
16212
16213        return null;
16214    }
16215
16216    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16217            boolean doingAll, long now) {
16218        if (mAdjSeq == app.adjSeq) {
16219            // This adjustment has already been computed.
16220            return app.curRawAdj;
16221        }
16222
16223        if (app.thread == null) {
16224            app.adjSeq = mAdjSeq;
16225            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16226            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16227            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16228        }
16229
16230        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16231        app.adjSource = null;
16232        app.adjTarget = null;
16233        app.empty = false;
16234        app.cached = false;
16235
16236        final int activitiesSize = app.activities.size();
16237
16238        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16239            // The max adjustment doesn't allow this app to be anything
16240            // below foreground, so it is not worth doing work for it.
16241            app.adjType = "fixed";
16242            app.adjSeq = mAdjSeq;
16243            app.curRawAdj = app.maxAdj;
16244            app.foregroundActivities = false;
16245            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16246            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16247            // System processes can do UI, and when they do we want to have
16248            // them trim their memory after the user leaves the UI.  To
16249            // facilitate this, here we need to determine whether or not it
16250            // is currently showing UI.
16251            app.systemNoUi = true;
16252            if (app == TOP_APP) {
16253                app.systemNoUi = false;
16254            } else if (activitiesSize > 0) {
16255                for (int j = 0; j < activitiesSize; j++) {
16256                    final ActivityRecord r = app.activities.get(j);
16257                    if (r.visible) {
16258                        app.systemNoUi = false;
16259                    }
16260                }
16261            }
16262            if (!app.systemNoUi) {
16263                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16264            }
16265            return (app.curAdj=app.maxAdj);
16266        }
16267
16268        app.systemNoUi = false;
16269
16270        // Determine the importance of the process, starting with most
16271        // important to least, and assign an appropriate OOM adjustment.
16272        int adj;
16273        int schedGroup;
16274        int procState;
16275        boolean foregroundActivities = false;
16276        BroadcastQueue queue;
16277        if (app == TOP_APP) {
16278            // The last app on the list is the foreground app.
16279            adj = ProcessList.FOREGROUND_APP_ADJ;
16280            schedGroup = Process.THREAD_GROUP_DEFAULT;
16281            app.adjType = "top-activity";
16282            foregroundActivities = true;
16283            procState = ActivityManager.PROCESS_STATE_TOP;
16284        } else if (app.instrumentationClass != null) {
16285            // Don't want to kill running instrumentation.
16286            adj = ProcessList.FOREGROUND_APP_ADJ;
16287            schedGroup = Process.THREAD_GROUP_DEFAULT;
16288            app.adjType = "instrumentation";
16289            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16290        } else if ((queue = isReceivingBroadcast(app)) != null) {
16291            // An app that is currently receiving a broadcast also
16292            // counts as being in the foreground for OOM killer purposes.
16293            // It's placed in a sched group based on the nature of the
16294            // broadcast as reflected by which queue it's active in.
16295            adj = ProcessList.FOREGROUND_APP_ADJ;
16296            schedGroup = (queue == mFgBroadcastQueue)
16297                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16298            app.adjType = "broadcast";
16299            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16300        } else if (app.executingServices.size() > 0) {
16301            // An app that is currently executing a service callback also
16302            // counts as being in the foreground.
16303            adj = ProcessList.FOREGROUND_APP_ADJ;
16304            schedGroup = app.execServicesFg ?
16305                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16306            app.adjType = "exec-service";
16307            procState = ActivityManager.PROCESS_STATE_SERVICE;
16308            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16309        } else {
16310            // As far as we know the process is empty.  We may change our mind later.
16311            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16312            // At this point we don't actually know the adjustment.  Use the cached adj
16313            // value that the caller wants us to.
16314            adj = cachedAdj;
16315            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16316            app.cached = true;
16317            app.empty = true;
16318            app.adjType = "cch-empty";
16319        }
16320
16321        // Examine all activities if not already foreground.
16322        if (!foregroundActivities && activitiesSize > 0) {
16323            for (int j = 0; j < activitiesSize; j++) {
16324                final ActivityRecord r = app.activities.get(j);
16325                if (r.app != app) {
16326                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16327                            + app + "?!?");
16328                    continue;
16329                }
16330                if (r.visible) {
16331                    // App has a visible activity; only upgrade adjustment.
16332                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16333                        adj = ProcessList.VISIBLE_APP_ADJ;
16334                        app.adjType = "visible";
16335                    }
16336                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16337                        procState = ActivityManager.PROCESS_STATE_TOP;
16338                    }
16339                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16340                    app.cached = false;
16341                    app.empty = false;
16342                    foregroundActivities = true;
16343                    break;
16344                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16345                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16346                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16347                        app.adjType = "pausing";
16348                    }
16349                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16350                        procState = ActivityManager.PROCESS_STATE_TOP;
16351                    }
16352                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16353                    app.cached = false;
16354                    app.empty = false;
16355                    foregroundActivities = true;
16356                } else if (r.state == ActivityState.STOPPING) {
16357                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16358                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16359                        app.adjType = "stopping";
16360                    }
16361                    // For the process state, we will at this point consider the
16362                    // process to be cached.  It will be cached either as an activity
16363                    // or empty depending on whether the activity is finishing.  We do
16364                    // this so that we can treat the process as cached for purposes of
16365                    // memory trimming (determing current memory level, trim command to
16366                    // send to process) since there can be an arbitrary number of stopping
16367                    // processes and they should soon all go into the cached state.
16368                    if (!r.finishing) {
16369                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16370                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16371                        }
16372                    }
16373                    app.cached = false;
16374                    app.empty = false;
16375                    foregroundActivities = true;
16376                } else {
16377                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16378                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16379                        app.adjType = "cch-act";
16380                    }
16381                }
16382            }
16383        }
16384
16385        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16386            if (app.foregroundServices) {
16387                // The user is aware of this app, so make it visible.
16388                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16389                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16390                app.cached = false;
16391                app.adjType = "fg-service";
16392                schedGroup = Process.THREAD_GROUP_DEFAULT;
16393            } else if (app.forcingToForeground != null) {
16394                // The user is aware of this app, so make it visible.
16395                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16396                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16397                app.cached = false;
16398                app.adjType = "force-fg";
16399                app.adjSource = app.forcingToForeground;
16400                schedGroup = Process.THREAD_GROUP_DEFAULT;
16401            }
16402        }
16403
16404        if (app == mHeavyWeightProcess) {
16405            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16406                // We don't want to kill the current heavy-weight process.
16407                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16408                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16409                app.cached = false;
16410                app.adjType = "heavy";
16411            }
16412            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16413                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16414            }
16415        }
16416
16417        if (app == mHomeProcess) {
16418            if (adj > ProcessList.HOME_APP_ADJ) {
16419                // This process is hosting what we currently consider to be the
16420                // home app, so we don't want to let it go into the background.
16421                adj = ProcessList.HOME_APP_ADJ;
16422                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16423                app.cached = false;
16424                app.adjType = "home";
16425            }
16426            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16427                procState = ActivityManager.PROCESS_STATE_HOME;
16428            }
16429        }
16430
16431        if (app == mPreviousProcess && app.activities.size() > 0) {
16432            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16433                // This was the previous process that showed UI to the user.
16434                // We want to try to keep it around more aggressively, to give
16435                // a good experience around switching between two apps.
16436                adj = ProcessList.PREVIOUS_APP_ADJ;
16437                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16438                app.cached = false;
16439                app.adjType = "previous";
16440            }
16441            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16442                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16443            }
16444        }
16445
16446        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16447                + " reason=" + app.adjType);
16448
16449        // By default, we use the computed adjustment.  It may be changed if
16450        // there are applications dependent on our services or providers, but
16451        // this gives us a baseline and makes sure we don't get into an
16452        // infinite recursion.
16453        app.adjSeq = mAdjSeq;
16454        app.curRawAdj = adj;
16455        app.hasStartedServices = false;
16456
16457        if (mBackupTarget != null && app == mBackupTarget.app) {
16458            // If possible we want to avoid killing apps while they're being backed up
16459            if (adj > ProcessList.BACKUP_APP_ADJ) {
16460                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16461                adj = ProcessList.BACKUP_APP_ADJ;
16462                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16463                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16464                }
16465                app.adjType = "backup";
16466                app.cached = false;
16467            }
16468            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16469                procState = ActivityManager.PROCESS_STATE_BACKUP;
16470            }
16471        }
16472
16473        boolean mayBeTop = false;
16474
16475        for (int is = app.services.size()-1;
16476                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16477                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16478                        || procState > ActivityManager.PROCESS_STATE_TOP);
16479                is--) {
16480            ServiceRecord s = app.services.valueAt(is);
16481            if (s.startRequested) {
16482                app.hasStartedServices = true;
16483                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16484                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16485                }
16486                if (app.hasShownUi && app != mHomeProcess) {
16487                    // If this process has shown some UI, let it immediately
16488                    // go to the LRU list because it may be pretty heavy with
16489                    // UI stuff.  We'll tag it with a label just to help
16490                    // debug and understand what is going on.
16491                    if (adj > ProcessList.SERVICE_ADJ) {
16492                        app.adjType = "cch-started-ui-services";
16493                    }
16494                } else {
16495                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16496                        // This service has seen some activity within
16497                        // recent memory, so we will keep its process ahead
16498                        // of the background processes.
16499                        if (adj > ProcessList.SERVICE_ADJ) {
16500                            adj = ProcessList.SERVICE_ADJ;
16501                            app.adjType = "started-services";
16502                            app.cached = false;
16503                        }
16504                    }
16505                    // If we have let the service slide into the background
16506                    // state, still have some text describing what it is doing
16507                    // even though the service no longer has an impact.
16508                    if (adj > ProcessList.SERVICE_ADJ) {
16509                        app.adjType = "cch-started-services";
16510                    }
16511                }
16512            }
16513            for (int conni = s.connections.size()-1;
16514                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16515                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16516                            || procState > ActivityManager.PROCESS_STATE_TOP);
16517                    conni--) {
16518                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16519                for (int i = 0;
16520                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16521                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16522                                || procState > ActivityManager.PROCESS_STATE_TOP);
16523                        i++) {
16524                    // XXX should compute this based on the max of
16525                    // all connected clients.
16526                    ConnectionRecord cr = clist.get(i);
16527                    if (cr.binding.client == app) {
16528                        // Binding to ourself is not interesting.
16529                        continue;
16530                    }
16531                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16532                        ProcessRecord client = cr.binding.client;
16533                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16534                                TOP_APP, doingAll, now);
16535                        int clientProcState = client.curProcState;
16536                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16537                            // If the other app is cached for any reason, for purposes here
16538                            // we are going to consider it empty.  The specific cached state
16539                            // doesn't propagate except under certain conditions.
16540                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16541                        }
16542                        String adjType = null;
16543                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16544                            // Not doing bind OOM management, so treat
16545                            // this guy more like a started service.
16546                            if (app.hasShownUi && app != mHomeProcess) {
16547                                // If this process has shown some UI, let it immediately
16548                                // go to the LRU list because it may be pretty heavy with
16549                                // UI stuff.  We'll tag it with a label just to help
16550                                // debug and understand what is going on.
16551                                if (adj > clientAdj) {
16552                                    adjType = "cch-bound-ui-services";
16553                                }
16554                                app.cached = false;
16555                                clientAdj = adj;
16556                                clientProcState = procState;
16557                            } else {
16558                                if (now >= (s.lastActivity
16559                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16560                                    // This service has not seen activity within
16561                                    // recent memory, so allow it to drop to the
16562                                    // LRU list if there is no other reason to keep
16563                                    // it around.  We'll also tag it with a label just
16564                                    // to help debug and undertand what is going on.
16565                                    if (adj > clientAdj) {
16566                                        adjType = "cch-bound-services";
16567                                    }
16568                                    clientAdj = adj;
16569                                }
16570                            }
16571                        }
16572                        if (adj > clientAdj) {
16573                            // If this process has recently shown UI, and
16574                            // the process that is binding to it is less
16575                            // important than being visible, then we don't
16576                            // care about the binding as much as we care
16577                            // about letting this process get into the LRU
16578                            // list to be killed and restarted if needed for
16579                            // memory.
16580                            if (app.hasShownUi && app != mHomeProcess
16581                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16582                                adjType = "cch-bound-ui-services";
16583                            } else {
16584                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16585                                        |Context.BIND_IMPORTANT)) != 0) {
16586                                    adj = clientAdj;
16587                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16588                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16589                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16590                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16591                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16592                                    adj = clientAdj;
16593                                } else {
16594                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16595                                        adj = ProcessList.VISIBLE_APP_ADJ;
16596                                    }
16597                                }
16598                                if (!client.cached) {
16599                                    app.cached = false;
16600                                }
16601                                adjType = "service";
16602                            }
16603                        }
16604                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16605                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16606                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16607                            }
16608                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16609                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16610                                    // Special handling of clients who are in the top state.
16611                                    // We *may* want to consider this process to be in the
16612                                    // top state as well, but only if there is not another
16613                                    // reason for it to be running.  Being on the top is a
16614                                    // special state, meaning you are specifically running
16615                                    // for the current top app.  If the process is already
16616                                    // running in the background for some other reason, it
16617                                    // is more important to continue considering it to be
16618                                    // in the background state.
16619                                    mayBeTop = true;
16620                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16621                                } else {
16622                                    // Special handling for above-top states (persistent
16623                                    // processes).  These should not bring the current process
16624                                    // into the top state, since they are not on top.  Instead
16625                                    // give them the best state after that.
16626                                    clientProcState =
16627                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16628                                }
16629                            }
16630                        } else {
16631                            if (clientProcState <
16632                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16633                                clientProcState =
16634                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16635                            }
16636                        }
16637                        if (procState > clientProcState) {
16638                            procState = clientProcState;
16639                        }
16640                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16641                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16642                            app.pendingUiClean = true;
16643                        }
16644                        if (adjType != null) {
16645                            app.adjType = adjType;
16646                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16647                                    .REASON_SERVICE_IN_USE;
16648                            app.adjSource = cr.binding.client;
16649                            app.adjSourceProcState = clientProcState;
16650                            app.adjTarget = s.name;
16651                        }
16652                    }
16653                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16654                        app.treatLikeActivity = true;
16655                    }
16656                    final ActivityRecord a = cr.activity;
16657                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16658                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16659                                (a.visible || a.state == ActivityState.RESUMED
16660                                 || a.state == ActivityState.PAUSING)) {
16661                            adj = ProcessList.FOREGROUND_APP_ADJ;
16662                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16663                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16664                            }
16665                            app.cached = false;
16666                            app.adjType = "service";
16667                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16668                                    .REASON_SERVICE_IN_USE;
16669                            app.adjSource = a;
16670                            app.adjSourceProcState = procState;
16671                            app.adjTarget = s.name;
16672                        }
16673                    }
16674                }
16675            }
16676        }
16677
16678        for (int provi = app.pubProviders.size()-1;
16679                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16680                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16681                        || procState > ActivityManager.PROCESS_STATE_TOP);
16682                provi--) {
16683            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16684            for (int i = cpr.connections.size()-1;
16685                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16686                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16687                            || procState > ActivityManager.PROCESS_STATE_TOP);
16688                    i--) {
16689                ContentProviderConnection conn = cpr.connections.get(i);
16690                ProcessRecord client = conn.client;
16691                if (client == app) {
16692                    // Being our own client is not interesting.
16693                    continue;
16694                }
16695                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16696                int clientProcState = client.curProcState;
16697                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16698                    // If the other app is cached for any reason, for purposes here
16699                    // we are going to consider it empty.
16700                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16701                }
16702                if (adj > clientAdj) {
16703                    if (app.hasShownUi && app != mHomeProcess
16704                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16705                        app.adjType = "cch-ui-provider";
16706                    } else {
16707                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16708                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16709                        app.adjType = "provider";
16710                    }
16711                    app.cached &= client.cached;
16712                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16713                            .REASON_PROVIDER_IN_USE;
16714                    app.adjSource = client;
16715                    app.adjSourceProcState = clientProcState;
16716                    app.adjTarget = cpr.name;
16717                }
16718                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16719                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16720                        // Special handling of clients who are in the top state.
16721                        // We *may* want to consider this process to be in the
16722                        // top state as well, but only if there is not another
16723                        // reason for it to be running.  Being on the top is a
16724                        // special state, meaning you are specifically running
16725                        // for the current top app.  If the process is already
16726                        // running in the background for some other reason, it
16727                        // is more important to continue considering it to be
16728                        // in the background state.
16729                        mayBeTop = true;
16730                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16731                    } else {
16732                        // Special handling for above-top states (persistent
16733                        // processes).  These should not bring the current process
16734                        // into the top state, since they are not on top.  Instead
16735                        // give them the best state after that.
16736                        clientProcState =
16737                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16738                    }
16739                }
16740                if (procState > clientProcState) {
16741                    procState = clientProcState;
16742                }
16743                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16744                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16745                }
16746            }
16747            // If the provider has external (non-framework) process
16748            // dependencies, ensure that its adjustment is at least
16749            // FOREGROUND_APP_ADJ.
16750            if (cpr.hasExternalProcessHandles()) {
16751                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16752                    adj = ProcessList.FOREGROUND_APP_ADJ;
16753                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16754                    app.cached = false;
16755                    app.adjType = "provider";
16756                    app.adjTarget = cpr.name;
16757                }
16758                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16759                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16760                }
16761            }
16762        }
16763
16764        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16765            // A client of one of our services or providers is in the top state.  We
16766            // *may* want to be in the top state, but not if we are already running in
16767            // the background for some other reason.  For the decision here, we are going
16768            // to pick out a few specific states that we want to remain in when a client
16769            // is top (states that tend to be longer-term) and otherwise allow it to go
16770            // to the top state.
16771            switch (procState) {
16772                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16773                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16774                case ActivityManager.PROCESS_STATE_SERVICE:
16775                    // These all are longer-term states, so pull them up to the top
16776                    // of the background states, but not all the way to the top state.
16777                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16778                    break;
16779                default:
16780                    // Otherwise, top is a better choice, so take it.
16781                    procState = ActivityManager.PROCESS_STATE_TOP;
16782                    break;
16783            }
16784        }
16785
16786        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16787            if (app.hasClientActivities) {
16788                // This is a cached process, but with client activities.  Mark it so.
16789                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16790                app.adjType = "cch-client-act";
16791            } else if (app.treatLikeActivity) {
16792                // This is a cached process, but somebody wants us to treat it like it has
16793                // an activity, okay!
16794                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16795                app.adjType = "cch-as-act";
16796            }
16797        }
16798
16799        if (adj == ProcessList.SERVICE_ADJ) {
16800            if (doingAll) {
16801                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16802                mNewNumServiceProcs++;
16803                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16804                if (!app.serviceb) {
16805                    // This service isn't far enough down on the LRU list to
16806                    // normally be a B service, but if we are low on RAM and it
16807                    // is large we want to force it down since we would prefer to
16808                    // keep launcher over it.
16809                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16810                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16811                        app.serviceHighRam = true;
16812                        app.serviceb = true;
16813                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16814                    } else {
16815                        mNewNumAServiceProcs++;
16816                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16817                    }
16818                } else {
16819                    app.serviceHighRam = false;
16820                }
16821            }
16822            if (app.serviceb) {
16823                adj = ProcessList.SERVICE_B_ADJ;
16824            }
16825        }
16826
16827        app.curRawAdj = adj;
16828
16829        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16830        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16831        if (adj > app.maxAdj) {
16832            adj = app.maxAdj;
16833            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16834                schedGroup = Process.THREAD_GROUP_DEFAULT;
16835            }
16836        }
16837
16838        // Do final modification to adj.  Everything we do between here and applying
16839        // the final setAdj must be done in this function, because we will also use
16840        // it when computing the final cached adj later.  Note that we don't need to
16841        // worry about this for max adj above, since max adj will always be used to
16842        // keep it out of the cached vaues.
16843        app.curAdj = app.modifyRawOomAdj(adj);
16844        app.curSchedGroup = schedGroup;
16845        app.curProcState = procState;
16846        app.foregroundActivities = foregroundActivities;
16847
16848        return app.curRawAdj;
16849    }
16850
16851    /**
16852     * Schedule PSS collection of a process.
16853     */
16854    void requestPssLocked(ProcessRecord proc, int procState) {
16855        if (mPendingPssProcesses.contains(proc)) {
16856            return;
16857        }
16858        if (mPendingPssProcesses.size() == 0) {
16859            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16860        }
16861        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16862        proc.pssProcState = procState;
16863        mPendingPssProcesses.add(proc);
16864    }
16865
16866    /**
16867     * Schedule PSS collection of all processes.
16868     */
16869    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16870        if (!always) {
16871            if (now < (mLastFullPssTime +
16872                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16873                return;
16874            }
16875        }
16876        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16877        mLastFullPssTime = now;
16878        mFullPssPending = true;
16879        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16880        mPendingPssProcesses.clear();
16881        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16882            ProcessRecord app = mLruProcesses.get(i);
16883            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16884                app.pssProcState = app.setProcState;
16885                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16886                        isSleeping(), now);
16887                mPendingPssProcesses.add(app);
16888            }
16889        }
16890        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16891    }
16892
16893    /**
16894     * Ask a given process to GC right now.
16895     */
16896    final void performAppGcLocked(ProcessRecord app) {
16897        try {
16898            app.lastRequestedGc = SystemClock.uptimeMillis();
16899            if (app.thread != null) {
16900                if (app.reportLowMemory) {
16901                    app.reportLowMemory = false;
16902                    app.thread.scheduleLowMemory();
16903                } else {
16904                    app.thread.processInBackground();
16905                }
16906            }
16907        } catch (Exception e) {
16908            // whatever.
16909        }
16910    }
16911
16912    /**
16913     * Returns true if things are idle enough to perform GCs.
16914     */
16915    private final boolean canGcNowLocked() {
16916        boolean processingBroadcasts = false;
16917        for (BroadcastQueue q : mBroadcastQueues) {
16918            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16919                processingBroadcasts = true;
16920            }
16921        }
16922        return !processingBroadcasts
16923                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16924    }
16925
16926    /**
16927     * Perform GCs on all processes that are waiting for it, but only
16928     * if things are idle.
16929     */
16930    final void performAppGcsLocked() {
16931        final int N = mProcessesToGc.size();
16932        if (N <= 0) {
16933            return;
16934        }
16935        if (canGcNowLocked()) {
16936            while (mProcessesToGc.size() > 0) {
16937                ProcessRecord proc = mProcessesToGc.remove(0);
16938                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16939                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16940                            <= SystemClock.uptimeMillis()) {
16941                        // To avoid spamming the system, we will GC processes one
16942                        // at a time, waiting a few seconds between each.
16943                        performAppGcLocked(proc);
16944                        scheduleAppGcsLocked();
16945                        return;
16946                    } else {
16947                        // It hasn't been long enough since we last GCed this
16948                        // process...  put it in the list to wait for its time.
16949                        addProcessToGcListLocked(proc);
16950                        break;
16951                    }
16952                }
16953            }
16954
16955            scheduleAppGcsLocked();
16956        }
16957    }
16958
16959    /**
16960     * If all looks good, perform GCs on all processes waiting for them.
16961     */
16962    final void performAppGcsIfAppropriateLocked() {
16963        if (canGcNowLocked()) {
16964            performAppGcsLocked();
16965            return;
16966        }
16967        // Still not idle, wait some more.
16968        scheduleAppGcsLocked();
16969    }
16970
16971    /**
16972     * Schedule the execution of all pending app GCs.
16973     */
16974    final void scheduleAppGcsLocked() {
16975        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16976
16977        if (mProcessesToGc.size() > 0) {
16978            // Schedule a GC for the time to the next process.
16979            ProcessRecord proc = mProcessesToGc.get(0);
16980            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16981
16982            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16983            long now = SystemClock.uptimeMillis();
16984            if (when < (now+GC_TIMEOUT)) {
16985                when = now + GC_TIMEOUT;
16986            }
16987            mHandler.sendMessageAtTime(msg, when);
16988        }
16989    }
16990
16991    /**
16992     * Add a process to the array of processes waiting to be GCed.  Keeps the
16993     * list in sorted order by the last GC time.  The process can't already be
16994     * on the list.
16995     */
16996    final void addProcessToGcListLocked(ProcessRecord proc) {
16997        boolean added = false;
16998        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16999            if (mProcessesToGc.get(i).lastRequestedGc <
17000                    proc.lastRequestedGc) {
17001                added = true;
17002                mProcessesToGc.add(i+1, proc);
17003                break;
17004            }
17005        }
17006        if (!added) {
17007            mProcessesToGc.add(0, proc);
17008        }
17009    }
17010
17011    /**
17012     * Set up to ask a process to GC itself.  This will either do it
17013     * immediately, or put it on the list of processes to gc the next
17014     * time things are idle.
17015     */
17016    final void scheduleAppGcLocked(ProcessRecord app) {
17017        long now = SystemClock.uptimeMillis();
17018        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17019            return;
17020        }
17021        if (!mProcessesToGc.contains(app)) {
17022            addProcessToGcListLocked(app);
17023            scheduleAppGcsLocked();
17024        }
17025    }
17026
17027    final void checkExcessivePowerUsageLocked(boolean doKills) {
17028        updateCpuStatsNow();
17029
17030        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17031        boolean doWakeKills = doKills;
17032        boolean doCpuKills = doKills;
17033        if (mLastPowerCheckRealtime == 0) {
17034            doWakeKills = false;
17035        }
17036        if (mLastPowerCheckUptime == 0) {
17037            doCpuKills = false;
17038        }
17039        if (stats.isScreenOn()) {
17040            doWakeKills = false;
17041        }
17042        final long curRealtime = SystemClock.elapsedRealtime();
17043        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17044        final long curUptime = SystemClock.uptimeMillis();
17045        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17046        mLastPowerCheckRealtime = curRealtime;
17047        mLastPowerCheckUptime = curUptime;
17048        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17049            doWakeKills = false;
17050        }
17051        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17052            doCpuKills = false;
17053        }
17054        int i = mLruProcesses.size();
17055        while (i > 0) {
17056            i--;
17057            ProcessRecord app = mLruProcesses.get(i);
17058            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17059                long wtime;
17060                synchronized (stats) {
17061                    wtime = stats.getProcessWakeTime(app.info.uid,
17062                            app.pid, curRealtime);
17063                }
17064                long wtimeUsed = wtime - app.lastWakeTime;
17065                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17066                if (DEBUG_POWER) {
17067                    StringBuilder sb = new StringBuilder(128);
17068                    sb.append("Wake for ");
17069                    app.toShortString(sb);
17070                    sb.append(": over ");
17071                    TimeUtils.formatDuration(realtimeSince, sb);
17072                    sb.append(" used ");
17073                    TimeUtils.formatDuration(wtimeUsed, sb);
17074                    sb.append(" (");
17075                    sb.append((wtimeUsed*100)/realtimeSince);
17076                    sb.append("%)");
17077                    Slog.i(TAG, sb.toString());
17078                    sb.setLength(0);
17079                    sb.append("CPU for ");
17080                    app.toShortString(sb);
17081                    sb.append(": over ");
17082                    TimeUtils.formatDuration(uptimeSince, sb);
17083                    sb.append(" used ");
17084                    TimeUtils.formatDuration(cputimeUsed, sb);
17085                    sb.append(" (");
17086                    sb.append((cputimeUsed*100)/uptimeSince);
17087                    sb.append("%)");
17088                    Slog.i(TAG, sb.toString());
17089                }
17090                // If a process has held a wake lock for more
17091                // than 50% of the time during this period,
17092                // that sounds bad.  Kill!
17093                if (doWakeKills && realtimeSince > 0
17094                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17095                    synchronized (stats) {
17096                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17097                                realtimeSince, wtimeUsed);
17098                    }
17099                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17100                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17101                } else if (doCpuKills && uptimeSince > 0
17102                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17103                    synchronized (stats) {
17104                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17105                                uptimeSince, cputimeUsed);
17106                    }
17107                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17108                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17109                } else {
17110                    app.lastWakeTime = wtime;
17111                    app.lastCpuTime = app.curCpuTime;
17112                }
17113            }
17114        }
17115    }
17116
17117    private final boolean applyOomAdjLocked(ProcessRecord app,
17118            ProcessRecord TOP_APP, boolean doingAll, long now) {
17119        boolean success = true;
17120
17121        if (app.curRawAdj != app.setRawAdj) {
17122            app.setRawAdj = app.curRawAdj;
17123        }
17124
17125        int changes = 0;
17126
17127        if (app.curAdj != app.setAdj) {
17128            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17129            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17130                TAG, "Set " + app.pid + " " + app.processName +
17131                " adj " + app.curAdj + ": " + app.adjType);
17132            app.setAdj = app.curAdj;
17133        }
17134
17135        if (app.setSchedGroup != app.curSchedGroup) {
17136            app.setSchedGroup = app.curSchedGroup;
17137            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17138                    "Setting process group of " + app.processName
17139                    + " to " + app.curSchedGroup);
17140            if (app.waitingToKill != null &&
17141                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17142                app.kill(app.waitingToKill, true);
17143                success = false;
17144            } else {
17145                if (true) {
17146                    long oldId = Binder.clearCallingIdentity();
17147                    try {
17148                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17149                    } catch (Exception e) {
17150                        Slog.w(TAG, "Failed setting process group of " + app.pid
17151                                + " to " + app.curSchedGroup);
17152                        e.printStackTrace();
17153                    } finally {
17154                        Binder.restoreCallingIdentity(oldId);
17155                    }
17156                } else {
17157                    if (app.thread != null) {
17158                        try {
17159                            app.thread.setSchedulingGroup(app.curSchedGroup);
17160                        } catch (RemoteException e) {
17161                        }
17162                    }
17163                }
17164                Process.setSwappiness(app.pid,
17165                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17166            }
17167        }
17168        if (app.repForegroundActivities != app.foregroundActivities) {
17169            app.repForegroundActivities = app.foregroundActivities;
17170            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17171        }
17172        if (app.repProcState != app.curProcState) {
17173            app.repProcState = app.curProcState;
17174            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17175            if (app.thread != null) {
17176                try {
17177                    if (false) {
17178                        //RuntimeException h = new RuntimeException("here");
17179                        Slog.i(TAG, "Sending new process state " + app.repProcState
17180                                + " to " + app /*, h*/);
17181                    }
17182                    app.thread.setProcessState(app.repProcState);
17183                } catch (RemoteException e) {
17184                }
17185            }
17186        }
17187        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17188                app.setProcState)) {
17189            app.lastStateTime = now;
17190            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17191                    isSleeping(), now);
17192            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17193                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17194                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17195                    + (app.nextPssTime-now) + ": " + app);
17196        } else {
17197            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17198                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17199                requestPssLocked(app, app.setProcState);
17200                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17201                        isSleeping(), now);
17202            } else if (false && DEBUG_PSS) {
17203                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17204            }
17205        }
17206        if (app.setProcState != app.curProcState) {
17207            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17208                    "Proc state change of " + app.processName
17209                    + " to " + app.curProcState);
17210            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17211            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17212            if (setImportant && !curImportant) {
17213                // This app is no longer something we consider important enough to allow to
17214                // use arbitrary amounts of battery power.  Note
17215                // its current wake lock time to later know to kill it if
17216                // it is not behaving well.
17217                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17218                synchronized (stats) {
17219                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17220                            app.pid, SystemClock.elapsedRealtime());
17221                }
17222                app.lastCpuTime = app.curCpuTime;
17223
17224            }
17225            app.setProcState = app.curProcState;
17226            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17227                app.notCachedSinceIdle = false;
17228            }
17229            if (!doingAll) {
17230                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17231            } else {
17232                app.procStateChanged = true;
17233            }
17234        }
17235
17236        if (changes != 0) {
17237            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17238            int i = mPendingProcessChanges.size()-1;
17239            ProcessChangeItem item = null;
17240            while (i >= 0) {
17241                item = mPendingProcessChanges.get(i);
17242                if (item.pid == app.pid) {
17243                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17244                    break;
17245                }
17246                i--;
17247            }
17248            if (i < 0) {
17249                // No existing item in pending changes; need a new one.
17250                final int NA = mAvailProcessChanges.size();
17251                if (NA > 0) {
17252                    item = mAvailProcessChanges.remove(NA-1);
17253                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17254                } else {
17255                    item = new ProcessChangeItem();
17256                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17257                }
17258                item.changes = 0;
17259                item.pid = app.pid;
17260                item.uid = app.info.uid;
17261                if (mPendingProcessChanges.size() == 0) {
17262                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17263                            "*** Enqueueing dispatch processes changed!");
17264                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17265                }
17266                mPendingProcessChanges.add(item);
17267            }
17268            item.changes |= changes;
17269            item.processState = app.repProcState;
17270            item.foregroundActivities = app.repForegroundActivities;
17271            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17272                    + Integer.toHexString(System.identityHashCode(item))
17273                    + " " + app.toShortString() + ": changes=" + item.changes
17274                    + " procState=" + item.processState
17275                    + " foreground=" + item.foregroundActivities
17276                    + " type=" + app.adjType + " source=" + app.adjSource
17277                    + " target=" + app.adjTarget);
17278        }
17279
17280        return success;
17281    }
17282
17283    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17284        if (proc.thread != null) {
17285            if (proc.baseProcessTracker != null) {
17286                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17287            }
17288            if (proc.repProcState >= 0) {
17289                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17290                        proc.repProcState);
17291            }
17292        }
17293    }
17294
17295    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17296            ProcessRecord TOP_APP, boolean doingAll, long now) {
17297        if (app.thread == null) {
17298            return false;
17299        }
17300
17301        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17302
17303        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17304    }
17305
17306    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17307            boolean oomAdj) {
17308        if (isForeground != proc.foregroundServices) {
17309            proc.foregroundServices = isForeground;
17310            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17311                    proc.info.uid);
17312            if (isForeground) {
17313                if (curProcs == null) {
17314                    curProcs = new ArrayList<ProcessRecord>();
17315                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17316                }
17317                if (!curProcs.contains(proc)) {
17318                    curProcs.add(proc);
17319                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17320                            proc.info.packageName, proc.info.uid);
17321                }
17322            } else {
17323                if (curProcs != null) {
17324                    if (curProcs.remove(proc)) {
17325                        mBatteryStatsService.noteEvent(
17326                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17327                                proc.info.packageName, proc.info.uid);
17328                        if (curProcs.size() <= 0) {
17329                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17330                        }
17331                    }
17332                }
17333            }
17334            if (oomAdj) {
17335                updateOomAdjLocked();
17336            }
17337        }
17338    }
17339
17340    private final ActivityRecord resumedAppLocked() {
17341        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17342        String pkg;
17343        int uid;
17344        if (act != null) {
17345            pkg = act.packageName;
17346            uid = act.info.applicationInfo.uid;
17347        } else {
17348            pkg = null;
17349            uid = -1;
17350        }
17351        // Has the UID or resumed package name changed?
17352        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17353                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17354            if (mCurResumedPackage != null) {
17355                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17356                        mCurResumedPackage, mCurResumedUid);
17357            }
17358            mCurResumedPackage = pkg;
17359            mCurResumedUid = uid;
17360            if (mCurResumedPackage != null) {
17361                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17362                        mCurResumedPackage, mCurResumedUid);
17363            }
17364        }
17365        return act;
17366    }
17367
17368    final boolean updateOomAdjLocked(ProcessRecord app) {
17369        final ActivityRecord TOP_ACT = resumedAppLocked();
17370        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17371        final boolean wasCached = app.cached;
17372
17373        mAdjSeq++;
17374
17375        // This is the desired cached adjusment we want to tell it to use.
17376        // If our app is currently cached, we know it, and that is it.  Otherwise,
17377        // we don't know it yet, and it needs to now be cached we will then
17378        // need to do a complete oom adj.
17379        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17380                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17381        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17382                SystemClock.uptimeMillis());
17383        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17384            // Changed to/from cached state, so apps after it in the LRU
17385            // list may also be changed.
17386            updateOomAdjLocked();
17387        }
17388        return success;
17389    }
17390
17391    final void updateOomAdjLocked() {
17392        final ActivityRecord TOP_ACT = resumedAppLocked();
17393        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17394        final long now = SystemClock.uptimeMillis();
17395        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17396        final int N = mLruProcesses.size();
17397
17398        if (false) {
17399            RuntimeException e = new RuntimeException();
17400            e.fillInStackTrace();
17401            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17402        }
17403
17404        mAdjSeq++;
17405        mNewNumServiceProcs = 0;
17406        mNewNumAServiceProcs = 0;
17407
17408        final int emptyProcessLimit;
17409        final int cachedProcessLimit;
17410        if (mProcessLimit <= 0) {
17411            emptyProcessLimit = cachedProcessLimit = 0;
17412        } else if (mProcessLimit == 1) {
17413            emptyProcessLimit = 1;
17414            cachedProcessLimit = 0;
17415        } else {
17416            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17417            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17418        }
17419
17420        // Let's determine how many processes we have running vs.
17421        // how many slots we have for background processes; we may want
17422        // to put multiple processes in a slot of there are enough of
17423        // them.
17424        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17425                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17426        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17427        if (numEmptyProcs > cachedProcessLimit) {
17428            // If there are more empty processes than our limit on cached
17429            // processes, then use the cached process limit for the factor.
17430            // This ensures that the really old empty processes get pushed
17431            // down to the bottom, so if we are running low on memory we will
17432            // have a better chance at keeping around more cached processes
17433            // instead of a gazillion empty processes.
17434            numEmptyProcs = cachedProcessLimit;
17435        }
17436        int emptyFactor = numEmptyProcs/numSlots;
17437        if (emptyFactor < 1) emptyFactor = 1;
17438        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17439        if (cachedFactor < 1) cachedFactor = 1;
17440        int stepCached = 0;
17441        int stepEmpty = 0;
17442        int numCached = 0;
17443        int numEmpty = 0;
17444        int numTrimming = 0;
17445
17446        mNumNonCachedProcs = 0;
17447        mNumCachedHiddenProcs = 0;
17448
17449        // First update the OOM adjustment for each of the
17450        // application processes based on their current state.
17451        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17452        int nextCachedAdj = curCachedAdj+1;
17453        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17454        int nextEmptyAdj = curEmptyAdj+2;
17455        for (int i=N-1; i>=0; i--) {
17456            ProcessRecord app = mLruProcesses.get(i);
17457            if (!app.killedByAm && app.thread != null) {
17458                app.procStateChanged = false;
17459                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17460
17461                // If we haven't yet assigned the final cached adj
17462                // to the process, do that now.
17463                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17464                    switch (app.curProcState) {
17465                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17466                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17467                            // This process is a cached process holding activities...
17468                            // assign it the next cached value for that type, and then
17469                            // step that cached level.
17470                            app.curRawAdj = curCachedAdj;
17471                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17472                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17473                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17474                                    + ")");
17475                            if (curCachedAdj != nextCachedAdj) {
17476                                stepCached++;
17477                                if (stepCached >= cachedFactor) {
17478                                    stepCached = 0;
17479                                    curCachedAdj = nextCachedAdj;
17480                                    nextCachedAdj += 2;
17481                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17482                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17483                                    }
17484                                }
17485                            }
17486                            break;
17487                        default:
17488                            // For everything else, assign next empty cached process
17489                            // level and bump that up.  Note that this means that
17490                            // long-running services that have dropped down to the
17491                            // cached level will be treated as empty (since their process
17492                            // state is still as a service), which is what we want.
17493                            app.curRawAdj = curEmptyAdj;
17494                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17495                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17496                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17497                                    + ")");
17498                            if (curEmptyAdj != nextEmptyAdj) {
17499                                stepEmpty++;
17500                                if (stepEmpty >= emptyFactor) {
17501                                    stepEmpty = 0;
17502                                    curEmptyAdj = nextEmptyAdj;
17503                                    nextEmptyAdj += 2;
17504                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17505                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17506                                    }
17507                                }
17508                            }
17509                            break;
17510                    }
17511                }
17512
17513                applyOomAdjLocked(app, TOP_APP, true, now);
17514
17515                // Count the number of process types.
17516                switch (app.curProcState) {
17517                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17518                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17519                        mNumCachedHiddenProcs++;
17520                        numCached++;
17521                        if (numCached > cachedProcessLimit) {
17522                            app.kill("cached #" + numCached, true);
17523                        }
17524                        break;
17525                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17526                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17527                                && app.lastActivityTime < oldTime) {
17528                            app.kill("empty for "
17529                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17530                                    / 1000) + "s", true);
17531                        } else {
17532                            numEmpty++;
17533                            if (numEmpty > emptyProcessLimit) {
17534                                app.kill("empty #" + numEmpty, true);
17535                            }
17536                        }
17537                        break;
17538                    default:
17539                        mNumNonCachedProcs++;
17540                        break;
17541                }
17542
17543                if (app.isolated && app.services.size() <= 0) {
17544                    // If this is an isolated process, and there are no
17545                    // services running in it, then the process is no longer
17546                    // needed.  We agressively kill these because we can by
17547                    // definition not re-use the same process again, and it is
17548                    // good to avoid having whatever code was running in them
17549                    // left sitting around after no longer needed.
17550                    app.kill("isolated not needed", true);
17551                }
17552
17553                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17554                        && !app.killedByAm) {
17555                    numTrimming++;
17556                }
17557            }
17558        }
17559
17560        mNumServiceProcs = mNewNumServiceProcs;
17561
17562        // Now determine the memory trimming level of background processes.
17563        // Unfortunately we need to start at the back of the list to do this
17564        // properly.  We only do this if the number of background apps we
17565        // are managing to keep around is less than half the maximum we desire;
17566        // if we are keeping a good number around, we'll let them use whatever
17567        // memory they want.
17568        final int numCachedAndEmpty = numCached + numEmpty;
17569        int memFactor;
17570        if (numCached <= ProcessList.TRIM_CACHED_APPS
17571                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17572            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17573                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17574            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17575                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17576            } else {
17577                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17578            }
17579        } else {
17580            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17581        }
17582        // We always allow the memory level to go up (better).  We only allow it to go
17583        // down if we are in a state where that is allowed, *and* the total number of processes
17584        // has gone down since last time.
17585        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17586                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17587                + " last=" + mLastNumProcesses);
17588        if (memFactor > mLastMemoryLevel) {
17589            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17590                memFactor = mLastMemoryLevel;
17591                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17592            }
17593        }
17594        mLastMemoryLevel = memFactor;
17595        mLastNumProcesses = mLruProcesses.size();
17596        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17597        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17598        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17599            if (mLowRamStartTime == 0) {
17600                mLowRamStartTime = now;
17601            }
17602            int step = 0;
17603            int fgTrimLevel;
17604            switch (memFactor) {
17605                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17606                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17607                    break;
17608                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17609                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17610                    break;
17611                default:
17612                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17613                    break;
17614            }
17615            int factor = numTrimming/3;
17616            int minFactor = 2;
17617            if (mHomeProcess != null) minFactor++;
17618            if (mPreviousProcess != null) minFactor++;
17619            if (factor < minFactor) factor = minFactor;
17620            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17621            for (int i=N-1; i>=0; i--) {
17622                ProcessRecord app = mLruProcesses.get(i);
17623                if (allChanged || app.procStateChanged) {
17624                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17625                    app.procStateChanged = false;
17626                }
17627                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17628                        && !app.killedByAm) {
17629                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17630                        try {
17631                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17632                                    "Trimming memory of " + app.processName
17633                                    + " to " + curLevel);
17634                            app.thread.scheduleTrimMemory(curLevel);
17635                        } catch (RemoteException e) {
17636                        }
17637                        if (false) {
17638                            // For now we won't do this; our memory trimming seems
17639                            // to be good enough at this point that destroying
17640                            // activities causes more harm than good.
17641                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17642                                    && app != mHomeProcess && app != mPreviousProcess) {
17643                                // Need to do this on its own message because the stack may not
17644                                // be in a consistent state at this point.
17645                                // For these apps we will also finish their activities
17646                                // to help them free memory.
17647                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17648                            }
17649                        }
17650                    }
17651                    app.trimMemoryLevel = curLevel;
17652                    step++;
17653                    if (step >= factor) {
17654                        step = 0;
17655                        switch (curLevel) {
17656                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17657                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17658                                break;
17659                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17660                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17661                                break;
17662                        }
17663                    }
17664                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17665                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17666                            && app.thread != null) {
17667                        try {
17668                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17669                                    "Trimming memory of heavy-weight " + app.processName
17670                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17671                            app.thread.scheduleTrimMemory(
17672                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17673                        } catch (RemoteException e) {
17674                        }
17675                    }
17676                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17677                } else {
17678                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17679                            || app.systemNoUi) && app.pendingUiClean) {
17680                        // If this application is now in the background and it
17681                        // had done UI, then give it the special trim level to
17682                        // have it free UI resources.
17683                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17684                        if (app.trimMemoryLevel < level && app.thread != null) {
17685                            try {
17686                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17687                                        "Trimming memory of bg-ui " + app.processName
17688                                        + " to " + level);
17689                                app.thread.scheduleTrimMemory(level);
17690                            } catch (RemoteException e) {
17691                            }
17692                        }
17693                        app.pendingUiClean = false;
17694                    }
17695                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17696                        try {
17697                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17698                                    "Trimming memory of fg " + app.processName
17699                                    + " to " + fgTrimLevel);
17700                            app.thread.scheduleTrimMemory(fgTrimLevel);
17701                        } catch (RemoteException e) {
17702                        }
17703                    }
17704                    app.trimMemoryLevel = fgTrimLevel;
17705                }
17706            }
17707        } else {
17708            if (mLowRamStartTime != 0) {
17709                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17710                mLowRamStartTime = 0;
17711            }
17712            for (int i=N-1; i>=0; i--) {
17713                ProcessRecord app = mLruProcesses.get(i);
17714                if (allChanged || app.procStateChanged) {
17715                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17716                    app.procStateChanged = false;
17717                }
17718                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17719                        || app.systemNoUi) && app.pendingUiClean) {
17720                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17721                            && app.thread != null) {
17722                        try {
17723                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17724                                    "Trimming memory of ui hidden " + app.processName
17725                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17726                            app.thread.scheduleTrimMemory(
17727                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17728                        } catch (RemoteException e) {
17729                        }
17730                    }
17731                    app.pendingUiClean = false;
17732                }
17733                app.trimMemoryLevel = 0;
17734            }
17735        }
17736
17737        if (mAlwaysFinishActivities) {
17738            // Need to do this on its own message because the stack may not
17739            // be in a consistent state at this point.
17740            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17741        }
17742
17743        if (allChanged) {
17744            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17745        }
17746
17747        if (mProcessStats.shouldWriteNowLocked(now)) {
17748            mHandler.post(new Runnable() {
17749                @Override public void run() {
17750                    synchronized (ActivityManagerService.this) {
17751                        mProcessStats.writeStateAsyncLocked();
17752                    }
17753                }
17754            });
17755        }
17756
17757        if (DEBUG_OOM_ADJ) {
17758            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17759        }
17760    }
17761
17762    final void trimApplications() {
17763        synchronized (this) {
17764            int i;
17765
17766            // First remove any unused application processes whose package
17767            // has been removed.
17768            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17769                final ProcessRecord app = mRemovedProcesses.get(i);
17770                if (app.activities.size() == 0
17771                        && app.curReceiver == null && app.services.size() == 0) {
17772                    Slog.i(
17773                        TAG, "Exiting empty application process "
17774                        + app.processName + " ("
17775                        + (app.thread != null ? app.thread.asBinder() : null)
17776                        + ")\n");
17777                    if (app.pid > 0 && app.pid != MY_PID) {
17778                        app.kill("empty", false);
17779                    } else {
17780                        try {
17781                            app.thread.scheduleExit();
17782                        } catch (Exception e) {
17783                            // Ignore exceptions.
17784                        }
17785                    }
17786                    cleanUpApplicationRecordLocked(app, false, true, -1);
17787                    mRemovedProcesses.remove(i);
17788
17789                    if (app.persistent) {
17790                        addAppLocked(app.info, false, null /* ABI override */);
17791                    }
17792                }
17793            }
17794
17795            // Now update the oom adj for all processes.
17796            updateOomAdjLocked();
17797        }
17798    }
17799
17800    /** This method sends the specified signal to each of the persistent apps */
17801    public void signalPersistentProcesses(int sig) throws RemoteException {
17802        if (sig != Process.SIGNAL_USR1) {
17803            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17804        }
17805
17806        synchronized (this) {
17807            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17808                    != PackageManager.PERMISSION_GRANTED) {
17809                throw new SecurityException("Requires permission "
17810                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17811            }
17812
17813            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17814                ProcessRecord r = mLruProcesses.get(i);
17815                if (r.thread != null && r.persistent) {
17816                    Process.sendSignal(r.pid, sig);
17817                }
17818            }
17819        }
17820    }
17821
17822    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17823        if (proc == null || proc == mProfileProc) {
17824            proc = mProfileProc;
17825            profileType = mProfileType;
17826            clearProfilerLocked();
17827        }
17828        if (proc == null) {
17829            return;
17830        }
17831        try {
17832            proc.thread.profilerControl(false, null, profileType);
17833        } catch (RemoteException e) {
17834            throw new IllegalStateException("Process disappeared");
17835        }
17836    }
17837
17838    private void clearProfilerLocked() {
17839        if (mProfileFd != null) {
17840            try {
17841                mProfileFd.close();
17842            } catch (IOException e) {
17843            }
17844        }
17845        mProfileApp = null;
17846        mProfileProc = null;
17847        mProfileFile = null;
17848        mProfileType = 0;
17849        mAutoStopProfiler = false;
17850        mSamplingInterval = 0;
17851    }
17852
17853    public boolean profileControl(String process, int userId, boolean start,
17854            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17855
17856        try {
17857            synchronized (this) {
17858                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17859                // its own permission.
17860                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17861                        != PackageManager.PERMISSION_GRANTED) {
17862                    throw new SecurityException("Requires permission "
17863                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17864                }
17865
17866                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17867                    throw new IllegalArgumentException("null profile info or fd");
17868                }
17869
17870                ProcessRecord proc = null;
17871                if (process != null) {
17872                    proc = findProcessLocked(process, userId, "profileControl");
17873                }
17874
17875                if (start && (proc == null || proc.thread == null)) {
17876                    throw new IllegalArgumentException("Unknown process: " + process);
17877                }
17878
17879                if (start) {
17880                    stopProfilerLocked(null, 0);
17881                    setProfileApp(proc.info, proc.processName, profilerInfo);
17882                    mProfileProc = proc;
17883                    mProfileType = profileType;
17884                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17885                    try {
17886                        fd = fd.dup();
17887                    } catch (IOException e) {
17888                        fd = null;
17889                    }
17890                    profilerInfo.profileFd = fd;
17891                    proc.thread.profilerControl(start, profilerInfo, profileType);
17892                    fd = null;
17893                    mProfileFd = null;
17894                } else {
17895                    stopProfilerLocked(proc, profileType);
17896                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17897                        try {
17898                            profilerInfo.profileFd.close();
17899                        } catch (IOException e) {
17900                        }
17901                    }
17902                }
17903
17904                return true;
17905            }
17906        } catch (RemoteException e) {
17907            throw new IllegalStateException("Process disappeared");
17908        } finally {
17909            if (profilerInfo != null && profilerInfo.profileFd != null) {
17910                try {
17911                    profilerInfo.profileFd.close();
17912                } catch (IOException e) {
17913                }
17914            }
17915        }
17916    }
17917
17918    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17919        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17920                userId, true, ALLOW_FULL_ONLY, callName, null);
17921        ProcessRecord proc = null;
17922        try {
17923            int pid = Integer.parseInt(process);
17924            synchronized (mPidsSelfLocked) {
17925                proc = mPidsSelfLocked.get(pid);
17926            }
17927        } catch (NumberFormatException e) {
17928        }
17929
17930        if (proc == null) {
17931            ArrayMap<String, SparseArray<ProcessRecord>> all
17932                    = mProcessNames.getMap();
17933            SparseArray<ProcessRecord> procs = all.get(process);
17934            if (procs != null && procs.size() > 0) {
17935                proc = procs.valueAt(0);
17936                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17937                    for (int i=1; i<procs.size(); i++) {
17938                        ProcessRecord thisProc = procs.valueAt(i);
17939                        if (thisProc.userId == userId) {
17940                            proc = thisProc;
17941                            break;
17942                        }
17943                    }
17944                }
17945            }
17946        }
17947
17948        return proc;
17949    }
17950
17951    public boolean dumpHeap(String process, int userId, boolean managed,
17952            String path, ParcelFileDescriptor fd) throws RemoteException {
17953
17954        try {
17955            synchronized (this) {
17956                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17957                // its own permission (same as profileControl).
17958                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17959                        != PackageManager.PERMISSION_GRANTED) {
17960                    throw new SecurityException("Requires permission "
17961                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17962                }
17963
17964                if (fd == null) {
17965                    throw new IllegalArgumentException("null fd");
17966                }
17967
17968                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17969                if (proc == null || proc.thread == null) {
17970                    throw new IllegalArgumentException("Unknown process: " + process);
17971                }
17972
17973                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17974                if (!isDebuggable) {
17975                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17976                        throw new SecurityException("Process not debuggable: " + proc);
17977                    }
17978                }
17979
17980                proc.thread.dumpHeap(managed, path, fd);
17981                fd = null;
17982                return true;
17983            }
17984        } catch (RemoteException e) {
17985            throw new IllegalStateException("Process disappeared");
17986        } finally {
17987            if (fd != null) {
17988                try {
17989                    fd.close();
17990                } catch (IOException e) {
17991                }
17992            }
17993        }
17994    }
17995
17996    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17997    public void monitor() {
17998        synchronized (this) { }
17999    }
18000
18001    void onCoreSettingsChange(Bundle settings) {
18002        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18003            ProcessRecord processRecord = mLruProcesses.get(i);
18004            try {
18005                if (processRecord.thread != null) {
18006                    processRecord.thread.setCoreSettings(settings);
18007                }
18008            } catch (RemoteException re) {
18009                /* ignore */
18010            }
18011        }
18012    }
18013
18014    // Multi-user methods
18015
18016    /**
18017     * Start user, if its not already running, but don't bring it to foreground.
18018     */
18019    @Override
18020    public boolean startUserInBackground(final int userId) {
18021        return startUser(userId, /* foreground */ false);
18022    }
18023
18024    /**
18025     * Start user, if its not already running, and bring it to foreground.
18026     */
18027    boolean startUserInForeground(final int userId, Dialog dlg) {
18028        boolean result = startUser(userId, /* foreground */ true);
18029        dlg.dismiss();
18030        return result;
18031    }
18032
18033    /**
18034     * Refreshes the list of users related to the current user when either a
18035     * user switch happens or when a new related user is started in the
18036     * background.
18037     */
18038    private void updateCurrentProfileIdsLocked() {
18039        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18040                mCurrentUserId, false /* enabledOnly */);
18041        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18042        for (int i = 0; i < currentProfileIds.length; i++) {
18043            currentProfileIds[i] = profiles.get(i).id;
18044        }
18045        mCurrentProfileIds = currentProfileIds;
18046
18047        synchronized (mUserProfileGroupIdsSelfLocked) {
18048            mUserProfileGroupIdsSelfLocked.clear();
18049            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18050            for (int i = 0; i < users.size(); i++) {
18051                UserInfo user = users.get(i);
18052                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18053                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18054                }
18055            }
18056        }
18057    }
18058
18059    private Set getProfileIdsLocked(int userId) {
18060        Set userIds = new HashSet<Integer>();
18061        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18062                userId, false /* enabledOnly */);
18063        for (UserInfo user : profiles) {
18064            userIds.add(Integer.valueOf(user.id));
18065        }
18066        return userIds;
18067    }
18068
18069    @Override
18070    public boolean switchUser(final int userId) {
18071        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18072        String userName;
18073        synchronized (this) {
18074            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18075            if (userInfo == null) {
18076                Slog.w(TAG, "No user info for user #" + userId);
18077                return false;
18078            }
18079            if (userInfo.isManagedProfile()) {
18080                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18081                return false;
18082            }
18083            userName = userInfo.name;
18084            mTargetUserId = userId;
18085        }
18086        mHandler.removeMessages(START_USER_SWITCH_MSG);
18087        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18088        return true;
18089    }
18090
18091    private void showUserSwitchDialog(int userId, String userName) {
18092        // The dialog will show and then initiate the user switch by calling startUserInForeground
18093        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18094                true /* above system */);
18095        d.show();
18096    }
18097
18098    private boolean startUser(final int userId, final boolean foreground) {
18099        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18100                != PackageManager.PERMISSION_GRANTED) {
18101            String msg = "Permission Denial: switchUser() from pid="
18102                    + Binder.getCallingPid()
18103                    + ", uid=" + Binder.getCallingUid()
18104                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18105            Slog.w(TAG, msg);
18106            throw new SecurityException(msg);
18107        }
18108
18109        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18110
18111        final long ident = Binder.clearCallingIdentity();
18112        try {
18113            synchronized (this) {
18114                final int oldUserId = mCurrentUserId;
18115                if (oldUserId == userId) {
18116                    return true;
18117                }
18118
18119                mStackSupervisor.setLockTaskModeLocked(null, false);
18120
18121                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18122                if (userInfo == null) {
18123                    Slog.w(TAG, "No user info for user #" + userId);
18124                    return false;
18125                }
18126                if (foreground && userInfo.isManagedProfile()) {
18127                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18128                    return false;
18129                }
18130
18131                if (foreground) {
18132                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18133                            R.anim.screen_user_enter);
18134                }
18135
18136                boolean needStart = false;
18137
18138                // If the user we are switching to is not currently started, then
18139                // we need to start it now.
18140                if (mStartedUsers.get(userId) == null) {
18141                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18142                    updateStartedUserArrayLocked();
18143                    needStart = true;
18144                }
18145
18146                final Integer userIdInt = Integer.valueOf(userId);
18147                mUserLru.remove(userIdInt);
18148                mUserLru.add(userIdInt);
18149
18150                if (foreground) {
18151                    mCurrentUserId = userId;
18152                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18153                    updateCurrentProfileIdsLocked();
18154                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18155                    // Once the internal notion of the active user has switched, we lock the device
18156                    // with the option to show the user switcher on the keyguard.
18157                    mWindowManager.lockNow(null);
18158                } else {
18159                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18160                    updateCurrentProfileIdsLocked();
18161                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18162                    mUserLru.remove(currentUserIdInt);
18163                    mUserLru.add(currentUserIdInt);
18164                }
18165
18166                final UserStartedState uss = mStartedUsers.get(userId);
18167
18168                // Make sure user is in the started state.  If it is currently
18169                // stopping, we need to knock that off.
18170                if (uss.mState == UserStartedState.STATE_STOPPING) {
18171                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18172                    // so we can just fairly silently bring the user back from
18173                    // the almost-dead.
18174                    uss.mState = UserStartedState.STATE_RUNNING;
18175                    updateStartedUserArrayLocked();
18176                    needStart = true;
18177                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18178                    // This means ACTION_SHUTDOWN has been sent, so we will
18179                    // need to treat this as a new boot of the user.
18180                    uss.mState = UserStartedState.STATE_BOOTING;
18181                    updateStartedUserArrayLocked();
18182                    needStart = true;
18183                }
18184
18185                if (uss.mState == UserStartedState.STATE_BOOTING) {
18186                    // Booting up a new user, need to tell system services about it.
18187                    // Note that this is on the same handler as scheduling of broadcasts,
18188                    // which is important because it needs to go first.
18189                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18190                }
18191
18192                if (foreground) {
18193                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18194                            oldUserId));
18195                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18196                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18197                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18198                            oldUserId, userId, uss));
18199                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18200                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18201                }
18202
18203                if (needStart) {
18204                    // Send USER_STARTED broadcast
18205                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18206                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18207                            | Intent.FLAG_RECEIVER_FOREGROUND);
18208                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18209                    broadcastIntentLocked(null, null, intent,
18210                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18211                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18212                }
18213
18214                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18215                    if (userId != UserHandle.USER_OWNER) {
18216                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18217                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18218                        broadcastIntentLocked(null, null, intent, null,
18219                                new IIntentReceiver.Stub() {
18220                                    public void performReceive(Intent intent, int resultCode,
18221                                            String data, Bundle extras, boolean ordered,
18222                                            boolean sticky, int sendingUser) {
18223                                        onUserInitialized(uss, foreground, oldUserId, userId);
18224                                    }
18225                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18226                                true, false, MY_PID, Process.SYSTEM_UID,
18227                                userId);
18228                        uss.initializing = true;
18229                    } else {
18230                        getUserManagerLocked().makeInitialized(userInfo.id);
18231                    }
18232                }
18233
18234                if (foreground) {
18235                    if (!uss.initializing) {
18236                        moveUserToForeground(uss, oldUserId, userId);
18237                    }
18238                } else {
18239                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18240                }
18241
18242                if (needStart) {
18243                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18244                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18245                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18246                    broadcastIntentLocked(null, null, intent,
18247                            null, new IIntentReceiver.Stub() {
18248                                @Override
18249                                public void performReceive(Intent intent, int resultCode, String data,
18250                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18251                                        throws RemoteException {
18252                                }
18253                            }, 0, null, null,
18254                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18255                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18256                }
18257            }
18258        } finally {
18259            Binder.restoreCallingIdentity(ident);
18260        }
18261
18262        return true;
18263    }
18264
18265    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18266        long ident = Binder.clearCallingIdentity();
18267        try {
18268            Intent intent;
18269            if (oldUserId >= 0) {
18270                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18271                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18272                int count = profiles.size();
18273                for (int i = 0; i < count; i++) {
18274                    int profileUserId = profiles.get(i).id;
18275                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18276                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18277                            | Intent.FLAG_RECEIVER_FOREGROUND);
18278                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18279                    broadcastIntentLocked(null, null, intent,
18280                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18281                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18282                }
18283            }
18284            if (newUserId >= 0) {
18285                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18286                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18287                int count = profiles.size();
18288                for (int i = 0; i < count; i++) {
18289                    int profileUserId = profiles.get(i).id;
18290                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18291                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18292                            | Intent.FLAG_RECEIVER_FOREGROUND);
18293                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18294                    broadcastIntentLocked(null, null, intent,
18295                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18296                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18297                }
18298                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18299                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18300                        | Intent.FLAG_RECEIVER_FOREGROUND);
18301                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18302                broadcastIntentLocked(null, null, intent,
18303                        null, null, 0, null, null,
18304                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18305                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18306            }
18307        } finally {
18308            Binder.restoreCallingIdentity(ident);
18309        }
18310    }
18311
18312    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18313            final int newUserId) {
18314        final int N = mUserSwitchObservers.beginBroadcast();
18315        if (N > 0) {
18316            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18317                int mCount = 0;
18318                @Override
18319                public void sendResult(Bundle data) throws RemoteException {
18320                    synchronized (ActivityManagerService.this) {
18321                        if (mCurUserSwitchCallback == this) {
18322                            mCount++;
18323                            if (mCount == N) {
18324                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18325                            }
18326                        }
18327                    }
18328                }
18329            };
18330            synchronized (this) {
18331                uss.switching = true;
18332                mCurUserSwitchCallback = callback;
18333            }
18334            for (int i=0; i<N; i++) {
18335                try {
18336                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18337                            newUserId, callback);
18338                } catch (RemoteException e) {
18339                }
18340            }
18341        } else {
18342            synchronized (this) {
18343                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18344            }
18345        }
18346        mUserSwitchObservers.finishBroadcast();
18347    }
18348
18349    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18350        synchronized (this) {
18351            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18352            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18353        }
18354    }
18355
18356    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18357        mCurUserSwitchCallback = null;
18358        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18359        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18360                oldUserId, newUserId, uss));
18361    }
18362
18363    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18364        synchronized (this) {
18365            if (foreground) {
18366                moveUserToForeground(uss, oldUserId, newUserId);
18367            }
18368        }
18369
18370        completeSwitchAndInitalize(uss, newUserId, true, false);
18371    }
18372
18373    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18374        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18375        if (homeInFront) {
18376            startHomeActivityLocked(newUserId);
18377        } else {
18378            mStackSupervisor.resumeTopActivitiesLocked();
18379        }
18380        EventLogTags.writeAmSwitchUser(newUserId);
18381        getUserManagerLocked().userForeground(newUserId);
18382        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18383    }
18384
18385    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18386        completeSwitchAndInitalize(uss, newUserId, false, true);
18387    }
18388
18389    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18390            boolean clearInitializing, boolean clearSwitching) {
18391        boolean unfrozen = false;
18392        synchronized (this) {
18393            if (clearInitializing) {
18394                uss.initializing = false;
18395                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18396            }
18397            if (clearSwitching) {
18398                uss.switching = false;
18399            }
18400            if (!uss.switching && !uss.initializing) {
18401                mWindowManager.stopFreezingScreen();
18402                unfrozen = true;
18403            }
18404        }
18405        if (unfrozen) {
18406            final int N = mUserSwitchObservers.beginBroadcast();
18407            for (int i=0; i<N; i++) {
18408                try {
18409                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18410                } catch (RemoteException e) {
18411                }
18412            }
18413            mUserSwitchObservers.finishBroadcast();
18414        }
18415    }
18416
18417    void scheduleStartProfilesLocked() {
18418        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18419            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18420                    DateUtils.SECOND_IN_MILLIS);
18421        }
18422    }
18423
18424    void startProfilesLocked() {
18425        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18426        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18427                mCurrentUserId, false /* enabledOnly */);
18428        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18429        for (UserInfo user : profiles) {
18430            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18431                    && user.id != mCurrentUserId) {
18432                toStart.add(user);
18433            }
18434        }
18435        final int n = toStart.size();
18436        int i = 0;
18437        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18438            startUserInBackground(toStart.get(i).id);
18439        }
18440        if (i < n) {
18441            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18442        }
18443    }
18444
18445    void finishUserBoot(UserStartedState uss) {
18446        synchronized (this) {
18447            if (uss.mState == UserStartedState.STATE_BOOTING
18448                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18449                uss.mState = UserStartedState.STATE_RUNNING;
18450                final int userId = uss.mHandle.getIdentifier();
18451                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18452                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18453                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18454                broadcastIntentLocked(null, null, intent,
18455                        null, null, 0, null, null,
18456                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18457                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18458            }
18459        }
18460    }
18461
18462    void finishUserSwitch(UserStartedState uss) {
18463        synchronized (this) {
18464            finishUserBoot(uss);
18465
18466            startProfilesLocked();
18467
18468            int num = mUserLru.size();
18469            int i = 0;
18470            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18471                Integer oldUserId = mUserLru.get(i);
18472                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18473                if (oldUss == null) {
18474                    // Shouldn't happen, but be sane if it does.
18475                    mUserLru.remove(i);
18476                    num--;
18477                    continue;
18478                }
18479                if (oldUss.mState == UserStartedState.STATE_STOPPING
18480                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18481                    // This user is already stopping, doesn't count.
18482                    num--;
18483                    i++;
18484                    continue;
18485                }
18486                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18487                    // Owner and current can't be stopped, but count as running.
18488                    i++;
18489                    continue;
18490                }
18491                // This is a user to be stopped.
18492                stopUserLocked(oldUserId, null);
18493                num--;
18494                i++;
18495            }
18496        }
18497    }
18498
18499    @Override
18500    public int stopUser(final int userId, final IStopUserCallback callback) {
18501        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18502                != PackageManager.PERMISSION_GRANTED) {
18503            String msg = "Permission Denial: switchUser() from pid="
18504                    + Binder.getCallingPid()
18505                    + ", uid=" + Binder.getCallingUid()
18506                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18507            Slog.w(TAG, msg);
18508            throw new SecurityException(msg);
18509        }
18510        if (userId <= 0) {
18511            throw new IllegalArgumentException("Can't stop primary user " + userId);
18512        }
18513        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18514        synchronized (this) {
18515            return stopUserLocked(userId, callback);
18516        }
18517    }
18518
18519    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18520        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18521        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18522            return ActivityManager.USER_OP_IS_CURRENT;
18523        }
18524
18525        final UserStartedState uss = mStartedUsers.get(userId);
18526        if (uss == null) {
18527            // User is not started, nothing to do...  but we do need to
18528            // callback if requested.
18529            if (callback != null) {
18530                mHandler.post(new Runnable() {
18531                    @Override
18532                    public void run() {
18533                        try {
18534                            callback.userStopped(userId);
18535                        } catch (RemoteException e) {
18536                        }
18537                    }
18538                });
18539            }
18540            return ActivityManager.USER_OP_SUCCESS;
18541        }
18542
18543        if (callback != null) {
18544            uss.mStopCallbacks.add(callback);
18545        }
18546
18547        if (uss.mState != UserStartedState.STATE_STOPPING
18548                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18549            uss.mState = UserStartedState.STATE_STOPPING;
18550            updateStartedUserArrayLocked();
18551
18552            long ident = Binder.clearCallingIdentity();
18553            try {
18554                // We are going to broadcast ACTION_USER_STOPPING and then
18555                // once that is done send a final ACTION_SHUTDOWN and then
18556                // stop the user.
18557                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18558                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18559                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18560                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18561                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18562                // This is the result receiver for the final shutdown broadcast.
18563                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18564                    @Override
18565                    public void performReceive(Intent intent, int resultCode, String data,
18566                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18567                        finishUserStop(uss);
18568                    }
18569                };
18570                // This is the result receiver for the initial stopping broadcast.
18571                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18572                    @Override
18573                    public void performReceive(Intent intent, int resultCode, String data,
18574                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18575                        // On to the next.
18576                        synchronized (ActivityManagerService.this) {
18577                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18578                                // Whoops, we are being started back up.  Abort, abort!
18579                                return;
18580                            }
18581                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18582                        }
18583                        mBatteryStatsService.noteEvent(
18584                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18585                                Integer.toString(userId), userId);
18586                        mSystemServiceManager.stopUser(userId);
18587                        broadcastIntentLocked(null, null, shutdownIntent,
18588                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18589                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18590                    }
18591                };
18592                // Kick things off.
18593                broadcastIntentLocked(null, null, stoppingIntent,
18594                        null, stoppingReceiver, 0, null, null,
18595                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18596                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18597            } finally {
18598                Binder.restoreCallingIdentity(ident);
18599            }
18600        }
18601
18602        return ActivityManager.USER_OP_SUCCESS;
18603    }
18604
18605    void finishUserStop(UserStartedState uss) {
18606        final int userId = uss.mHandle.getIdentifier();
18607        boolean stopped;
18608        ArrayList<IStopUserCallback> callbacks;
18609        synchronized (this) {
18610            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18611            if (mStartedUsers.get(userId) != uss) {
18612                stopped = false;
18613            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18614                stopped = false;
18615            } else {
18616                stopped = true;
18617                // User can no longer run.
18618                mStartedUsers.remove(userId);
18619                mUserLru.remove(Integer.valueOf(userId));
18620                updateStartedUserArrayLocked();
18621
18622                // Clean up all state and processes associated with the user.
18623                // Kill all the processes for the user.
18624                forceStopUserLocked(userId, "finish user");
18625            }
18626
18627            // Explicitly remove the old information in mRecentTasks.
18628            removeRecentTasksForUserLocked(userId);
18629        }
18630
18631        for (int i=0; i<callbacks.size(); i++) {
18632            try {
18633                if (stopped) callbacks.get(i).userStopped(userId);
18634                else callbacks.get(i).userStopAborted(userId);
18635            } catch (RemoteException e) {
18636            }
18637        }
18638
18639        if (stopped) {
18640            mSystemServiceManager.cleanupUser(userId);
18641            synchronized (this) {
18642                mStackSupervisor.removeUserLocked(userId);
18643            }
18644        }
18645    }
18646
18647    @Override
18648    public UserInfo getCurrentUser() {
18649        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18650                != PackageManager.PERMISSION_GRANTED) && (
18651                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18652                != PackageManager.PERMISSION_GRANTED)) {
18653            String msg = "Permission Denial: getCurrentUser() from pid="
18654                    + Binder.getCallingPid()
18655                    + ", uid=" + Binder.getCallingUid()
18656                    + " requires " + INTERACT_ACROSS_USERS;
18657            Slog.w(TAG, msg);
18658            throw new SecurityException(msg);
18659        }
18660        synchronized (this) {
18661            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18662            return getUserManagerLocked().getUserInfo(userId);
18663        }
18664    }
18665
18666    int getCurrentUserIdLocked() {
18667        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18668    }
18669
18670    @Override
18671    public boolean isUserRunning(int userId, boolean orStopped) {
18672        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18673                != PackageManager.PERMISSION_GRANTED) {
18674            String msg = "Permission Denial: isUserRunning() from pid="
18675                    + Binder.getCallingPid()
18676                    + ", uid=" + Binder.getCallingUid()
18677                    + " requires " + INTERACT_ACROSS_USERS;
18678            Slog.w(TAG, msg);
18679            throw new SecurityException(msg);
18680        }
18681        synchronized (this) {
18682            return isUserRunningLocked(userId, orStopped);
18683        }
18684    }
18685
18686    boolean isUserRunningLocked(int userId, boolean orStopped) {
18687        UserStartedState state = mStartedUsers.get(userId);
18688        if (state == null) {
18689            return false;
18690        }
18691        if (orStopped) {
18692            return true;
18693        }
18694        return state.mState != UserStartedState.STATE_STOPPING
18695                && state.mState != UserStartedState.STATE_SHUTDOWN;
18696    }
18697
18698    @Override
18699    public int[] getRunningUserIds() {
18700        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18701                != PackageManager.PERMISSION_GRANTED) {
18702            String msg = "Permission Denial: isUserRunning() from pid="
18703                    + Binder.getCallingPid()
18704                    + ", uid=" + Binder.getCallingUid()
18705                    + " requires " + INTERACT_ACROSS_USERS;
18706            Slog.w(TAG, msg);
18707            throw new SecurityException(msg);
18708        }
18709        synchronized (this) {
18710            return mStartedUserArray;
18711        }
18712    }
18713
18714    private void updateStartedUserArrayLocked() {
18715        int num = 0;
18716        for (int i=0; i<mStartedUsers.size();  i++) {
18717            UserStartedState uss = mStartedUsers.valueAt(i);
18718            // This list does not include stopping users.
18719            if (uss.mState != UserStartedState.STATE_STOPPING
18720                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18721                num++;
18722            }
18723        }
18724        mStartedUserArray = new int[num];
18725        num = 0;
18726        for (int i=0; i<mStartedUsers.size();  i++) {
18727            UserStartedState uss = mStartedUsers.valueAt(i);
18728            if (uss.mState != UserStartedState.STATE_STOPPING
18729                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18730                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18731                num++;
18732            }
18733        }
18734    }
18735
18736    @Override
18737    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18738        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18739                != PackageManager.PERMISSION_GRANTED) {
18740            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18741                    + Binder.getCallingPid()
18742                    + ", uid=" + Binder.getCallingUid()
18743                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18744            Slog.w(TAG, msg);
18745            throw new SecurityException(msg);
18746        }
18747
18748        mUserSwitchObservers.register(observer);
18749    }
18750
18751    @Override
18752    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18753        mUserSwitchObservers.unregister(observer);
18754    }
18755
18756    private boolean userExists(int userId) {
18757        if (userId == 0) {
18758            return true;
18759        }
18760        UserManagerService ums = getUserManagerLocked();
18761        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18762    }
18763
18764    int[] getUsersLocked() {
18765        UserManagerService ums = getUserManagerLocked();
18766        return ums != null ? ums.getUserIds() : new int[] { 0 };
18767    }
18768
18769    UserManagerService getUserManagerLocked() {
18770        if (mUserManager == null) {
18771            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18772            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18773        }
18774        return mUserManager;
18775    }
18776
18777    private int applyUserId(int uid, int userId) {
18778        return UserHandle.getUid(userId, uid);
18779    }
18780
18781    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18782        if (info == null) return null;
18783        ApplicationInfo newInfo = new ApplicationInfo(info);
18784        newInfo.uid = applyUserId(info.uid, userId);
18785        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18786                + info.packageName;
18787        return newInfo;
18788    }
18789
18790    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18791        if (aInfo == null
18792                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18793            return aInfo;
18794        }
18795
18796        ActivityInfo info = new ActivityInfo(aInfo);
18797        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18798        return info;
18799    }
18800
18801    private final class LocalService extends ActivityManagerInternal {
18802        @Override
18803        public void goingToSleep() {
18804            ActivityManagerService.this.goingToSleep();
18805        }
18806
18807        @Override
18808        public void wakingUp() {
18809            ActivityManagerService.this.wakingUp();
18810        }
18811
18812        @Override
18813        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18814                String processName, String abiOverride, int uid, Runnable crashHandler) {
18815            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18816                    processName, abiOverride, uid, crashHandler);
18817        }
18818    }
18819
18820    /**
18821     * An implementation of IAppTask, that allows an app to manage its own tasks via
18822     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18823     * only the process that calls getAppTasks() can call the AppTask methods.
18824     */
18825    class AppTaskImpl extends IAppTask.Stub {
18826        private int mTaskId;
18827        private int mCallingUid;
18828
18829        public AppTaskImpl(int taskId, int callingUid) {
18830            mTaskId = taskId;
18831            mCallingUid = callingUid;
18832        }
18833
18834        private void checkCaller() {
18835            if (mCallingUid != Binder.getCallingUid()) {
18836                throw new SecurityException("Caller " + mCallingUid
18837                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18838            }
18839        }
18840
18841        @Override
18842        public void finishAndRemoveTask() {
18843            checkCaller();
18844
18845            synchronized (ActivityManagerService.this) {
18846                long origId = Binder.clearCallingIdentity();
18847                try {
18848                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18849                    if (tr == null) {
18850                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18851                    }
18852                    // Only kill the process if we are not a new document
18853                    int flags = tr.getBaseIntent().getFlags();
18854                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18855                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18856                    removeTaskByIdLocked(mTaskId,
18857                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18858                } finally {
18859                    Binder.restoreCallingIdentity(origId);
18860                }
18861            }
18862        }
18863
18864        @Override
18865        public ActivityManager.RecentTaskInfo getTaskInfo() {
18866            checkCaller();
18867
18868            synchronized (ActivityManagerService.this) {
18869                long origId = Binder.clearCallingIdentity();
18870                try {
18871                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18872                    if (tr == null) {
18873                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18874                    }
18875                    return createRecentTaskInfoFromTaskRecord(tr);
18876                } finally {
18877                    Binder.restoreCallingIdentity(origId);
18878                }
18879            }
18880        }
18881
18882        @Override
18883        public void moveToFront() {
18884            checkCaller();
18885
18886            final TaskRecord tr;
18887            synchronized (ActivityManagerService.this) {
18888                tr = recentTaskForIdLocked(mTaskId);
18889                if (tr == null) {
18890                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18891                }
18892                if (tr.getRootActivity() != null) {
18893                    long origId = Binder.clearCallingIdentity();
18894                    try {
18895                        moveTaskToFrontLocked(tr.taskId, 0, null);
18896                        return;
18897                    } finally {
18898                        Binder.restoreCallingIdentity(origId);
18899                    }
18900                }
18901            }
18902
18903            startActivityFromRecentsInner(tr.taskId, null);
18904        }
18905
18906        @Override
18907        public int startActivity(IBinder whoThread, String callingPackage,
18908                Intent intent, String resolvedType, Bundle options) {
18909            checkCaller();
18910
18911            int callingUser = UserHandle.getCallingUserId();
18912            TaskRecord tr;
18913            IApplicationThread appThread;
18914            synchronized (ActivityManagerService.this) {
18915                tr = recentTaskForIdLocked(mTaskId);
18916                if (tr == null) {
18917                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18918                }
18919                appThread = ApplicationThreadNative.asInterface(whoThread);
18920                if (appThread == null) {
18921                    throw new IllegalArgumentException("Bad app thread " + appThread);
18922                }
18923            }
18924            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18925                    resolvedType, null, null, null, null, 0, 0, null, null,
18926                    null, options, callingUser, null, tr);
18927        }
18928
18929        @Override
18930        public void setExcludeFromRecents(boolean exclude) {
18931            checkCaller();
18932
18933            synchronized (ActivityManagerService.this) {
18934                long origId = Binder.clearCallingIdentity();
18935                try {
18936                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18937                    if (tr == null) {
18938                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18939                    }
18940                    Intent intent = tr.getBaseIntent();
18941                    if (exclude) {
18942                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18943                    } else {
18944                        intent.setFlags(intent.getFlags()
18945                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18946                    }
18947                } finally {
18948                    Binder.restoreCallingIdentity(origId);
18949                }
18950            }
18951        }
18952    }
18953}
18954