ActivityManagerService.java revision 01945f240a0cad450b5a417cf9380066f5736a01
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 com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
31import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
32import static org.xmlpull.v1.XmlPullParser.START_TAG;
33import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ProfilerInfo;
42import android.app.admin.DevicePolicyManager;
43import android.app.usage.UsageEvents;
44import android.app.usage.UsageStatsManagerInternal;
45import android.appwidget.AppWidgetManager;
46import android.content.res.Resources;
47import android.graphics.Bitmap;
48import android.graphics.Point;
49import android.graphics.Rect;
50import android.os.BatteryStats;
51import android.os.PersistableBundle;
52import android.os.storage.IMountService;
53import android.os.storage.StorageManager;
54import android.service.voice.IVoiceInteractionSession;
55import android.util.ArrayMap;
56import android.util.ArraySet;
57import android.util.SparseIntArray;
58
59import com.android.internal.R;
60import com.android.internal.annotations.GuardedBy;
61import com.android.internal.app.IAppOpsService;
62import com.android.internal.app.IVoiceInteractor;
63import com.android.internal.app.ProcessMap;
64import com.android.internal.app.ProcessStats;
65import com.android.internal.content.PackageMonitor;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.UserManagerService;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203import dalvik.system.VMRuntime;
204
205import java.io.BufferedInputStream;
206import java.io.BufferedOutputStream;
207import java.io.DataInputStream;
208import java.io.DataOutputStream;
209import java.io.File;
210import java.io.FileDescriptor;
211import java.io.FileInputStream;
212import java.io.FileNotFoundException;
213import java.io.FileOutputStream;
214import java.io.IOException;
215import java.io.InputStreamReader;
216import java.io.PrintWriter;
217import java.io.StringWriter;
218import java.lang.ref.WeakReference;
219import java.util.ArrayList;
220import java.util.Arrays;
221import java.util.Collections;
222import java.util.Comparator;
223import java.util.HashMap;
224import java.util.HashSet;
225import java.util.Iterator;
226import java.util.List;
227import java.util.Locale;
228import java.util.Map;
229import java.util.Set;
230import java.util.concurrent.atomic.AtomicBoolean;
231import java.util.concurrent.atomic.AtomicLong;
232
233public final class ActivityManagerService extends ActivityManagerNative
234        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
235
236    private static final String USER_DATA_DIR = "/data/user/";
237    // File that stores last updated system version and called preboot receivers
238    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
239
240    static final String TAG = "ActivityManager";
241    static final String TAG_MU = "ActivityManagerServiceMU";
242    static final boolean DEBUG = false;
243    static final boolean localLOGV = DEBUG;
244    static final boolean DEBUG_BACKUP = localLOGV || false;
245    static final boolean DEBUG_BROADCAST = localLOGV || false;
246    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_CLEANUP = localLOGV || false;
249    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
250    static final boolean DEBUG_FOCUS = false;
251    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
252    static final boolean DEBUG_MU = localLOGV || false;
253    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
254    static final boolean DEBUG_LRU = localLOGV || false;
255    static final boolean DEBUG_PAUSE = localLOGV || false;
256    static final boolean DEBUG_POWER = localLOGV || false;
257    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
258    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
259    static final boolean DEBUG_PROCESSES = localLOGV || false;
260    static final boolean DEBUG_PROVIDER = localLOGV || false;
261    static final boolean DEBUG_RESULTS = localLOGV || false;
262    static final boolean DEBUG_SERVICE = localLOGV || false;
263    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
264    static final boolean DEBUG_STACK = localLOGV || false;
265    static final boolean DEBUG_SWITCH = localLOGV || false;
266    static final boolean DEBUG_TASKS = localLOGV || false;
267    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
268    static final boolean DEBUG_TRANSITION = localLOGV || false;
269    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
270    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
271    static final boolean DEBUG_VISBILITY = localLOGV || false;
272    static final boolean DEBUG_PSS = localLOGV || false;
273    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
274    static final boolean DEBUG_RECENTS = localLOGV || false;
275    static final boolean VALIDATE_TOKENS = false;
276    static final boolean SHOW_ACTIVITY_START_TIME = true;
277
278    // Control over CPU and battery monitoring.
279    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
280    static final boolean MONITOR_CPU_USAGE = true;
281    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
282    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
283    static final boolean MONITOR_THREAD_CPU_USAGE = false;
284
285    // The flags that are set for all calls we make to the package manager.
286    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
287
288    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
289
290    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
291
292    // Maximum number recent bitmaps to keep in memory.
293    static final int MAX_RECENT_BITMAPS = 5;
294
295    // Amount of time after a call to stopAppSwitches() during which we will
296    // prevent further untrusted switches from happening.
297    static final long APP_SWITCH_DELAY_TIME = 5*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real.
301    static final int PROC_START_TIMEOUT = 10*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real, when the process was
305    // started with a wrapper for instrumentation (such as Valgrind) because it
306    // could take much longer than usual.
307    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
308
309    // How long to wait after going idle before forcing apps to GC.
310    static final int GC_TIMEOUT = 5*1000;
311
312    // The minimum amount of time between successive GC requests for a process.
313    static final int GC_MIN_INTERVAL = 60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process.
316    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process
319    // when the request is due to the memory state being lowered.
320    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
321
322    // The rate at which we check for apps using excessive power -- 15 mins.
323    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on wake locks to start killing things.
327    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on CPU usage to start killing things.
331    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // How long we allow a receiver to run before giving up on it.
334    static final int BROADCAST_FG_TIMEOUT = 10*1000;
335    static final int BROADCAST_BG_TIMEOUT = 60*1000;
336
337    // How long we wait until we timeout on key dispatching.
338    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
339
340    // How long we wait until we timeout on key dispatching during instrumentation.
341    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
342
343    // Amount of time we wait for observers to handle a user switch before
344    // giving up on them and unfreezing the screen.
345    static final int USER_SWITCH_TIMEOUT = 2*1000;
346
347    // Maximum number of users we allow to be running at a time.
348    static final int MAX_RUNNING_USERS = 3;
349
350    // How long to wait in getAssistContextExtras for the activity and foreground services
351    // to respond with the result.
352    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
353
354    // Maximum number of persisted Uri grants a package is allowed
355    static final int MAX_PERSISTED_URI_GRANTS = 128;
356
357    static final int MY_PID = Process.myPid();
358
359    static final String[] EMPTY_STRING_ARRAY = new String[0];
360
361    // How many bytes to write into the dropbox log before truncating
362    static final int DROPBOX_MAX_SIZE = 256 * 1024;
363
364    // Access modes for handleIncomingUser.
365    static final int ALLOW_NON_FULL = 0;
366    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
367    static final int ALLOW_FULL_ONLY = 2;
368
369    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
370
371    /** All system services */
372    SystemServiceManager mSystemServiceManager;
373
374    /** Run all ActivityStacks through this */
375    ActivityStackSupervisor mStackSupervisor;
376
377    public IntentFirewall mIntentFirewall;
378
379    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
380    // default actuion automatically.  Important for devices without direct input
381    // devices.
382    private boolean mShowDialogs = true;
383
384    BroadcastQueue mFgBroadcastQueue;
385    BroadcastQueue mBgBroadcastQueue;
386    // Convenient for easy iteration over the queues. Foreground is first
387    // so that dispatch of foreground broadcasts gets precedence.
388    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
389
390    BroadcastQueue broadcastQueueForIntent(Intent intent) {
391        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
392        if (DEBUG_BACKGROUND_BROADCAST) {
393            Slog.i(TAG, "Broadcast intent " + intent + " on "
394                    + (isFg ? "foreground" : "background")
395                    + " queue");
396        }
397        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
398    }
399
400    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
401        for (BroadcastQueue queue : mBroadcastQueues) {
402            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
403            if (r != null) {
404                return r;
405            }
406        }
407        return null;
408    }
409
410    /**
411     * Activity we have told the window manager to have key focus.
412     */
413    ActivityRecord mFocusedActivity = null;
414
415    /**
416     * List of intents that were used to start the most recent tasks.
417     */
418    ArrayList<TaskRecord> mRecentTasks;
419    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
420
421    /**
422     * For addAppTask: cached of the last activity component that was added.
423     */
424    ComponentName mLastAddedTaskComponent;
425
426    /**
427     * For addAppTask: cached of the last activity uid that was added.
428     */
429    int mLastAddedTaskUid;
430
431    /**
432     * For addAppTask: cached of the last ActivityInfo that was added.
433     */
434    ActivityInfo mLastAddedTaskActivity;
435
436    public class PendingAssistExtras extends Binder implements Runnable {
437        public final ActivityRecord activity;
438        public boolean haveResult = false;
439        public Bundle result = null;
440        public PendingAssistExtras(ActivityRecord _activity) {
441            activity = _activity;
442        }
443        @Override
444        public void run() {
445            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
446            synchronized (this) {
447                haveResult = true;
448                notifyAll();
449            }
450        }
451    }
452
453    final ArrayList<PendingAssistExtras> mPendingAssistExtras
454            = new ArrayList<PendingAssistExtras>();
455
456    /**
457     * Process management.
458     */
459    final ProcessList mProcessList = new ProcessList();
460
461    /**
462     * All of the applications we currently have running organized by name.
463     * The keys are strings of the application package name (as
464     * returned by the package manager), and the keys are ApplicationRecord
465     * objects.
466     */
467    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
468
469    /**
470     * Tracking long-term execution of processes to look for abuse and other
471     * bad app behavior.
472     */
473    final ProcessStatsService mProcessStats;
474
475    /**
476     * The currently running isolated processes.
477     */
478    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
479
480    /**
481     * Counter for assigning isolated process uids, to avoid frequently reusing the
482     * same ones.
483     */
484    int mNextIsolatedProcessUid = 0;
485
486    /**
487     * The currently running heavy-weight process, if any.
488     */
489    ProcessRecord mHeavyWeightProcess = null;
490
491    /**
492     * The last time that various processes have crashed.
493     */
494    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
495
496    /**
497     * Information about a process that is currently marked as bad.
498     */
499    static final class BadProcessInfo {
500        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
501            this.time = time;
502            this.shortMsg = shortMsg;
503            this.longMsg = longMsg;
504            this.stack = stack;
505        }
506
507        final long time;
508        final String shortMsg;
509        final String longMsg;
510        final String stack;
511    }
512
513    /**
514     * Set of applications that we consider to be bad, and will reject
515     * incoming broadcasts from (which the user has no control over).
516     * Processes are added to this set when they have crashed twice within
517     * a minimum amount of time; they are removed from it when they are
518     * later restarted (hopefully due to some user action).  The value is the
519     * time it was added to the list.
520     */
521    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
522
523    /**
524     * All of the processes we currently have running organized by pid.
525     * The keys are the pid running the application.
526     *
527     * <p>NOTE: This object is protected by its own lock, NOT the global
528     * activity manager lock!
529     */
530    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
531
532    /**
533     * All of the processes that have been forced to be foreground.  The key
534     * is the pid of the caller who requested it (we hold a death
535     * link on it).
536     */
537    abstract class ForegroundToken implements IBinder.DeathRecipient {
538        int pid;
539        IBinder token;
540    }
541    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
542
543    /**
544     * List of records for processes that someone had tried to start before the
545     * system was ready.  We don't start them at that point, but ensure they
546     * are started by the time booting is complete.
547     */
548    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
549
550    /**
551     * List of persistent applications that are in the process
552     * of being started.
553     */
554    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
555
556    /**
557     * Processes that are being forcibly torn down.
558     */
559    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
560
561    /**
562     * List of running applications, sorted by recent usage.
563     * The first entry in the list is the least recently used.
564     */
565    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Where in mLruProcesses that the processes hosting activities start.
569     */
570    int mLruProcessActivityStart = 0;
571
572    /**
573     * Where in mLruProcesses that the processes hosting services start.
574     * This is after (lower index) than mLruProcessesActivityStart.
575     */
576    int mLruProcessServiceStart = 0;
577
578    /**
579     * List of processes that should gc as soon as things are idle.
580     */
581    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
582
583    /**
584     * Processes we want to collect PSS data from.
585     */
586    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
587
588    /**
589     * Last time we requested PSS data of all processes.
590     */
591    long mLastFullPssTime = SystemClock.uptimeMillis();
592
593    /**
594     * If set, the next time we collect PSS data we should do a full collection
595     * with data from native processes and the kernel.
596     */
597    boolean mFullPssPending = false;
598
599    /**
600     * This is the process holding what we currently consider to be
601     * the "home" activity.
602     */
603    ProcessRecord mHomeProcess;
604
605    /**
606     * This is the process holding the activity the user last visited that
607     * is in a different process from the one they are currently in.
608     */
609    ProcessRecord mPreviousProcess;
610
611    /**
612     * The time at which the previous process was last visible.
613     */
614    long mPreviousProcessVisibleTime;
615
616    /**
617     * Which uses have been started, so are allowed to run code.
618     */
619    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
620
621    /**
622     * LRU list of history of current users.  Most recently current is at the end.
623     */
624    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
625
626    /**
627     * Constant array of the users that are currently started.
628     */
629    int[] mStartedUserArray = new int[] { 0 };
630
631    /**
632     * Registered observers of the user switching mechanics.
633     */
634    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
635            = new RemoteCallbackList<IUserSwitchObserver>();
636
637    /**
638     * Currently active user switch.
639     */
640    Object mCurUserSwitchCallback;
641
642    /**
643     * Packages that the user has asked to have run in screen size
644     * compatibility mode instead of filling the screen.
645     */
646    final CompatModePackages mCompatModePackages;
647
648    /**
649     * Set of IntentSenderRecord objects that are currently active.
650     */
651    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
652            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
653
654    /**
655     * Fingerprints (hashCode()) of stack traces that we've
656     * already logged DropBox entries for.  Guarded by itself.  If
657     * something (rogue user app) forces this over
658     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
659     */
660    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
661    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
662
663    /**
664     * Strict Mode background batched logging state.
665     *
666     * The string buffer is guarded by itself, and its lock is also
667     * used to determine if another batched write is already
668     * in-flight.
669     */
670    private final StringBuilder mStrictModeBuffer = new StringBuilder();
671
672    /**
673     * Keeps track of all IIntentReceivers that have been registered for
674     * broadcasts.  Hash keys are the receiver IBinder, hash value is
675     * a ReceiverList.
676     */
677    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
678            new HashMap<IBinder, ReceiverList>();
679
680    /**
681     * Resolver for broadcast intents to registered receivers.
682     * Holds BroadcastFilter (subclass of IntentFilter).
683     */
684    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
685            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
686        @Override
687        protected boolean allowFilterResult(
688                BroadcastFilter filter, List<BroadcastFilter> dest) {
689            IBinder target = filter.receiverList.receiver.asBinder();
690            for (int i=dest.size()-1; i>=0; i--) {
691                if (dest.get(i).receiverList.receiver.asBinder() == target) {
692                    return false;
693                }
694            }
695            return true;
696        }
697
698        @Override
699        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
700            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
701                    || userId == filter.owningUserId) {
702                return super.newResult(filter, match, userId);
703            }
704            return null;
705        }
706
707        @Override
708        protected BroadcastFilter[] newArray(int size) {
709            return new BroadcastFilter[size];
710        }
711
712        @Override
713        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
714            return packageName.equals(filter.packageName);
715        }
716    };
717
718    /**
719     * State of all active sticky broadcasts per user.  Keys are the action of the
720     * sticky Intent, values are an ArrayList of all broadcasted intents with
721     * that action (which should usually be one).  The SparseArray is keyed
722     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
723     * for stickies that are sent to all users.
724     */
725    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
726            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
727
728    final ActiveServices mServices;
729
730    /**
731     * Backup/restore process management
732     */
733    String mBackupAppName = null;
734    BackupRecord mBackupTarget = null;
735
736    final ProviderMap mProviderMap;
737
738    /**
739     * List of content providers who have clients waiting for them.  The
740     * application is currently being launched and the provider will be
741     * removed from this list once it is published.
742     */
743    final ArrayList<ContentProviderRecord> mLaunchingProviders
744            = new ArrayList<ContentProviderRecord>();
745
746    /**
747     * File storing persisted {@link #mGrantedUriPermissions}.
748     */
749    private final AtomicFile mGrantFile;
750
751    /** XML constants used in {@link #mGrantFile} */
752    private static final String TAG_URI_GRANTS = "uri-grants";
753    private static final String TAG_URI_GRANT = "uri-grant";
754    private static final String ATTR_USER_HANDLE = "userHandle";
755    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
756    private static final String ATTR_TARGET_USER_ID = "targetUserId";
757    private static final String ATTR_SOURCE_PKG = "sourcePkg";
758    private static final String ATTR_TARGET_PKG = "targetPkg";
759    private static final String ATTR_URI = "uri";
760    private static final String ATTR_MODE_FLAGS = "modeFlags";
761    private static final String ATTR_CREATED_TIME = "createdTime";
762    private static final String ATTR_PREFIX = "prefix";
763
764    /**
765     * Global set of specific {@link Uri} permissions that have been granted.
766     * This optimized lookup structure maps from {@link UriPermission#targetUid}
767     * to {@link UriPermission#uri} to {@link UriPermission}.
768     */
769    @GuardedBy("this")
770    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
771            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
772
773    public static class GrantUri {
774        public final int sourceUserId;
775        public final Uri uri;
776        public boolean prefix;
777
778        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
779            this.sourceUserId = sourceUserId;
780            this.uri = uri;
781            this.prefix = prefix;
782        }
783
784        @Override
785        public int hashCode() {
786            return toString().hashCode();
787        }
788
789        @Override
790        public boolean equals(Object o) {
791            if (o instanceof GrantUri) {
792                GrantUri other = (GrantUri) o;
793                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
794                        && prefix == other.prefix;
795            }
796            return false;
797        }
798
799        @Override
800        public String toString() {
801            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
802            if (prefix) result += " [prefix]";
803            return result;
804        }
805
806        public String toSafeString() {
807            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
808            if (prefix) result += " [prefix]";
809            return result;
810        }
811
812        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
813            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
814                    ContentProvider.getUriWithoutUserId(uri), false);
815        }
816    }
817
818    CoreSettingsObserver mCoreSettingsObserver;
819
820    /**
821     * Thread-local storage used to carry caller permissions over through
822     * indirect content-provider access.
823     */
824    private class Identity {
825        public int pid;
826        public int uid;
827
828        Identity(int _pid, int _uid) {
829            pid = _pid;
830            uid = _uid;
831        }
832    }
833
834    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
835
836    /**
837     * All information we have collected about the runtime performance of
838     * any user id that can impact battery performance.
839     */
840    final BatteryStatsService mBatteryStatsService;
841
842    /**
843     * Information about component usage
844     */
845    UsageStatsManagerInternal mUsageStatsService;
846
847    /**
848     * Information about and control over application operations
849     */
850    final AppOpsService mAppOpsService;
851
852    /**
853     * Save recent tasks information across reboots.
854     */
855    final TaskPersister mTaskPersister;
856
857    /**
858     * Current configuration information.  HistoryRecord objects are given
859     * a reference to this object to indicate which configuration they are
860     * currently running in, so this object must be kept immutable.
861     */
862    Configuration mConfiguration = new Configuration();
863
864    /**
865     * Current sequencing integer of the configuration, for skipping old
866     * configurations.
867     */
868    int mConfigurationSeq = 0;
869
870    /**
871     * Hardware-reported OpenGLES version.
872     */
873    final int GL_ES_VERSION;
874
875    /**
876     * List of initialization arguments to pass to all processes when binding applications to them.
877     * For example, references to the commonly used services.
878     */
879    HashMap<String, IBinder> mAppBindArgs;
880
881    /**
882     * Temporary to avoid allocations.  Protected by main lock.
883     */
884    final StringBuilder mStringBuilder = new StringBuilder(256);
885
886    /**
887     * Used to control how we initialize the service.
888     */
889    ComponentName mTopComponent;
890    String mTopAction = Intent.ACTION_MAIN;
891    String mTopData;
892    boolean mProcessesReady = false;
893    boolean mSystemReady = false;
894    boolean mBooting = false;
895    boolean mCallFinishBooting = false;
896    boolean mBootAnimationComplete = false;
897    boolean mWaitingUpdate = false;
898    boolean mDidUpdate = false;
899    boolean mOnBattery = false;
900    boolean mLaunchWarningShown = false;
901
902    Context mContext;
903
904    int mFactoryTest;
905
906    boolean mCheckedForSetup;
907
908    /**
909     * The time at which we will allow normal application switches again,
910     * after a call to {@link #stopAppSwitches()}.
911     */
912    long mAppSwitchesAllowedTime;
913
914    /**
915     * This is set to true after the first switch after mAppSwitchesAllowedTime
916     * is set; any switches after that will clear the time.
917     */
918    boolean mDidAppSwitch;
919
920    /**
921     * Last time (in realtime) at which we checked for power usage.
922     */
923    long mLastPowerCheckRealtime;
924
925    /**
926     * Last time (in uptime) at which we checked for power usage.
927     */
928    long mLastPowerCheckUptime;
929
930    /**
931     * Set while we are wanting to sleep, to prevent any
932     * activities from being started/resumed.
933     */
934    private boolean mSleeping = false;
935
936    /**
937     * Set while we are running a voice interaction.  This overrides
938     * sleeping while it is active.
939     */
940    private boolean mRunningVoice = false;
941
942    /**
943     * State of external calls telling us if the device is asleep.
944     */
945    private boolean mWentToSleep = false;
946
947    /**
948     * State of external call telling us if the lock screen is shown.
949     */
950    private boolean mLockScreenShown = false;
951
952    /**
953     * Set if we are shutting down the system, similar to sleeping.
954     */
955    boolean mShuttingDown = false;
956
957    /**
958     * Current sequence id for oom_adj computation traversal.
959     */
960    int mAdjSeq = 0;
961
962    /**
963     * Current sequence id for process LRU updating.
964     */
965    int mLruSeq = 0;
966
967    /**
968     * Keep track of the non-cached/empty process we last found, to help
969     * determine how to distribute cached/empty processes next time.
970     */
971    int mNumNonCachedProcs = 0;
972
973    /**
974     * Keep track of the number of cached hidden procs, to balance oom adj
975     * distribution between those and empty procs.
976     */
977    int mNumCachedHiddenProcs = 0;
978
979    /**
980     * Keep track of the number of service processes we last found, to
981     * determine on the next iteration which should be B services.
982     */
983    int mNumServiceProcs = 0;
984    int mNewNumAServiceProcs = 0;
985    int mNewNumServiceProcs = 0;
986
987    /**
988     * Allow the current computed overall memory level of the system to go down?
989     * This is set to false when we are killing processes for reasons other than
990     * memory management, so that the now smaller process list will not be taken as
991     * an indication that memory is tighter.
992     */
993    boolean mAllowLowerMemLevel = false;
994
995    /**
996     * The last computed memory level, for holding when we are in a state that
997     * processes are going away for other reasons.
998     */
999    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1000
1001    /**
1002     * The last total number of process we have, to determine if changes actually look
1003     * like a shrinking number of process due to lower RAM.
1004     */
1005    int mLastNumProcesses;
1006
1007    /**
1008     * The uptime of the last time we performed idle maintenance.
1009     */
1010    long mLastIdleTime = SystemClock.uptimeMillis();
1011
1012    /**
1013     * Total time spent with RAM that has been added in the past since the last idle time.
1014     */
1015    long mLowRamTimeSinceLastIdle = 0;
1016
1017    /**
1018     * If RAM is currently low, when that horrible situation started.
1019     */
1020    long mLowRamStartTime = 0;
1021
1022    /**
1023     * For reporting to battery stats the current top application.
1024     */
1025    private String mCurResumedPackage = null;
1026    private int mCurResumedUid = -1;
1027
1028    /**
1029     * For reporting to battery stats the apps currently running foreground
1030     * service.  The ProcessMap is package/uid tuples; each of these contain
1031     * an array of the currently foreground processes.
1032     */
1033    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1034            = new ProcessMap<ArrayList<ProcessRecord>>();
1035
1036    /**
1037     * This is set if we had to do a delayed dexopt of an app before launching
1038     * it, to increase the ANR timeouts in that case.
1039     */
1040    boolean mDidDexOpt;
1041
1042    /**
1043     * Set if the systemServer made a call to enterSafeMode.
1044     */
1045    boolean mSafeMode;
1046
1047    String mDebugApp = null;
1048    boolean mWaitForDebugger = false;
1049    boolean mDebugTransient = false;
1050    String mOrigDebugApp = null;
1051    boolean mOrigWaitForDebugger = false;
1052    boolean mAlwaysFinishActivities = false;
1053    IActivityController mController = null;
1054    String mProfileApp = null;
1055    ProcessRecord mProfileProc = null;
1056    String mProfileFile;
1057    ParcelFileDescriptor mProfileFd;
1058    int mSamplingInterval = 0;
1059    boolean mAutoStopProfiler = false;
1060    int mProfileType = 0;
1061    String mOpenGlTraceApp = null;
1062
1063    static class ProcessChangeItem {
1064        static final int CHANGE_ACTIVITIES = 1<<0;
1065        static final int CHANGE_PROCESS_STATE = 1<<1;
1066        int changes;
1067        int uid;
1068        int pid;
1069        int processState;
1070        boolean foregroundActivities;
1071    }
1072
1073    final RemoteCallbackList<IProcessObserver> mProcessObservers
1074            = new RemoteCallbackList<IProcessObserver>();
1075    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1076
1077    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1078            = new ArrayList<ProcessChangeItem>();
1079    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1080            = new ArrayList<ProcessChangeItem>();
1081
1082    /**
1083     * Runtime CPU use collection thread.  This object's lock is used to
1084     * perform synchronization with the thread (notifying it to run).
1085     */
1086    final Thread mProcessCpuThread;
1087
1088    /**
1089     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1090     * Must acquire this object's lock when accessing it.
1091     * NOTE: this lock will be held while doing long operations (trawling
1092     * through all processes in /proc), so it should never be acquired by
1093     * any critical paths such as when holding the main activity manager lock.
1094     */
1095    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1096            MONITOR_THREAD_CPU_USAGE);
1097    final AtomicLong mLastCpuTime = new AtomicLong(0);
1098    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1099
1100    long mLastWriteTime = 0;
1101
1102    /**
1103     * Used to retain an update lock when the foreground activity is in
1104     * immersive mode.
1105     */
1106    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1107
1108    /**
1109     * Set to true after the system has finished booting.
1110     */
1111    boolean mBooted = false;
1112
1113    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1114    int mProcessLimitOverride = -1;
1115
1116    WindowManagerService mWindowManager;
1117
1118    final ActivityThread mSystemThread;
1119
1120    // Holds the current foreground user's id
1121    int mCurrentUserId = 0;
1122    // Holds the target user's id during a user switch
1123    int mTargetUserId = UserHandle.USER_NULL;
1124    // If there are multiple profiles for the current user, their ids are here
1125    // Currently only the primary user can have managed profiles
1126    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1127
1128    /**
1129     * Mapping from each known user ID to the profile group ID it is associated with.
1130     */
1131    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1132
1133    private UserManagerService mUserManager;
1134
1135    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1136        final ProcessRecord mApp;
1137        final int mPid;
1138        final IApplicationThread mAppThread;
1139
1140        AppDeathRecipient(ProcessRecord app, int pid,
1141                IApplicationThread thread) {
1142            if (localLOGV) Slog.v(
1143                TAG, "New death recipient " + this
1144                + " for thread " + thread.asBinder());
1145            mApp = app;
1146            mPid = pid;
1147            mAppThread = thread;
1148        }
1149
1150        @Override
1151        public void binderDied() {
1152            if (localLOGV) Slog.v(
1153                TAG, "Death received in " + this
1154                + " for thread " + mAppThread.asBinder());
1155            synchronized(ActivityManagerService.this) {
1156                appDiedLocked(mApp, mPid, mAppThread);
1157            }
1158        }
1159    }
1160
1161    static final int SHOW_ERROR_MSG = 1;
1162    static final int SHOW_NOT_RESPONDING_MSG = 2;
1163    static final int SHOW_FACTORY_ERROR_MSG = 3;
1164    static final int UPDATE_CONFIGURATION_MSG = 4;
1165    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1166    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1167    static final int SERVICE_TIMEOUT_MSG = 12;
1168    static final int UPDATE_TIME_ZONE = 13;
1169    static final int SHOW_UID_ERROR_MSG = 14;
1170    static final int IM_FEELING_LUCKY_MSG = 15;
1171    static final int PROC_START_TIMEOUT_MSG = 20;
1172    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1173    static final int KILL_APPLICATION_MSG = 22;
1174    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1175    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1176    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1177    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1178    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1179    static final int CLEAR_DNS_CACHE_MSG = 28;
1180    static final int UPDATE_HTTP_PROXY_MSG = 29;
1181    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1182    static final int DISPATCH_PROCESSES_CHANGED = 31;
1183    static final int DISPATCH_PROCESS_DIED = 32;
1184    static final int REPORT_MEM_USAGE_MSG = 33;
1185    static final int REPORT_USER_SWITCH_MSG = 34;
1186    static final int CONTINUE_USER_SWITCH_MSG = 35;
1187    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1188    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1189    static final int PERSIST_URI_GRANTS_MSG = 38;
1190    static final int REQUEST_ALL_PSS_MSG = 39;
1191    static final int START_PROFILES_MSG = 40;
1192    static final int UPDATE_TIME = 41;
1193    static final int SYSTEM_USER_START_MSG = 42;
1194    static final int SYSTEM_USER_CURRENT_MSG = 43;
1195    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1196    static final int FINISH_BOOTING_MSG = 45;
1197    static final int START_USER_SWITCH_MSG = 46;
1198    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1199
1200    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1201    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1202    static final int FIRST_COMPAT_MODE_MSG = 300;
1203    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1204
1205    AlertDialog mUidAlert;
1206    CompatModeDialog mCompatModeDialog;
1207    long mLastMemUsageReportTime = 0;
1208
1209    private LockToAppRequestDialog mLockToAppRequest;
1210
1211    /**
1212     * Flag whether the current user is a "monkey", i.e. whether
1213     * the UI is driven by a UI automation tool.
1214     */
1215    private boolean mUserIsMonkey;
1216
1217    /** Flag whether the device has a Recents UI */
1218    boolean mHasRecents;
1219
1220    /** The dimensions of the thumbnails in the Recents UI. */
1221    int mThumbnailWidth;
1222    int mThumbnailHeight;
1223
1224    final ServiceThread mHandlerThread;
1225    final MainHandler mHandler;
1226
1227    final class MainHandler extends Handler {
1228        public MainHandler(Looper looper) {
1229            super(looper, null, true);
1230        }
1231
1232        @Override
1233        public void handleMessage(Message msg) {
1234            switch (msg.what) {
1235            case SHOW_ERROR_MSG: {
1236                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1237                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1238                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1239                synchronized (ActivityManagerService.this) {
1240                    ProcessRecord proc = (ProcessRecord)data.get("app");
1241                    AppErrorResult res = (AppErrorResult) data.get("result");
1242                    if (proc != null && proc.crashDialog != null) {
1243                        Slog.e(TAG, "App already has crash dialog: " + proc);
1244                        if (res != null) {
1245                            res.set(0);
1246                        }
1247                        return;
1248                    }
1249                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1250                            >= Process.FIRST_APPLICATION_UID
1251                            && proc.pid != MY_PID);
1252                    for (int userId : mCurrentProfileIds) {
1253                        isBackground &= (proc.userId != userId);
1254                    }
1255                    if (isBackground && !showBackground) {
1256                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1257                        if (res != null) {
1258                            res.set(0);
1259                        }
1260                        return;
1261                    }
1262                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1263                        Dialog d = new AppErrorDialog(mContext,
1264                                ActivityManagerService.this, res, proc);
1265                        d.show();
1266                        proc.crashDialog = d;
1267                    } else {
1268                        // The device is asleep, so just pretend that the user
1269                        // saw a crash dialog and hit "force quit".
1270                        if (res != null) {
1271                            res.set(0);
1272                        }
1273                    }
1274                }
1275
1276                ensureBootCompleted();
1277            } break;
1278            case SHOW_NOT_RESPONDING_MSG: {
1279                synchronized (ActivityManagerService.this) {
1280                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1281                    ProcessRecord proc = (ProcessRecord)data.get("app");
1282                    if (proc != null && proc.anrDialog != null) {
1283                        Slog.e(TAG, "App already has anr dialog: " + proc);
1284                        return;
1285                    }
1286
1287                    Intent intent = new Intent("android.intent.action.ANR");
1288                    if (!mProcessesReady) {
1289                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1290                                | Intent.FLAG_RECEIVER_FOREGROUND);
1291                    }
1292                    broadcastIntentLocked(null, null, intent,
1293                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1294                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1295
1296                    if (mShowDialogs) {
1297                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1298                                mContext, proc, (ActivityRecord)data.get("activity"),
1299                                msg.arg1 != 0);
1300                        d.show();
1301                        proc.anrDialog = d;
1302                    } else {
1303                        // Just kill the app if there is no dialog to be shown.
1304                        killAppAtUsersRequest(proc, null);
1305                    }
1306                }
1307
1308                ensureBootCompleted();
1309            } break;
1310            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1311                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord proc = (ProcessRecord) data.get("app");
1314                    if (proc == null) {
1315                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1316                        break;
1317                    }
1318                    if (proc.crashDialog != null) {
1319                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1320                        return;
1321                    }
1322                    AppErrorResult res = (AppErrorResult) data.get("result");
1323                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1324                        Dialog d = new StrictModeViolationDialog(mContext,
1325                                ActivityManagerService.this, res, proc);
1326                        d.show();
1327                        proc.crashDialog = d;
1328                    } else {
1329                        // The device is asleep, so just pretend that the user
1330                        // saw a crash dialog and hit "force quit".
1331                        res.set(0);
1332                    }
1333                }
1334                ensureBootCompleted();
1335            } break;
1336            case SHOW_FACTORY_ERROR_MSG: {
1337                Dialog d = new FactoryErrorDialog(
1338                    mContext, msg.getData().getCharSequence("msg"));
1339                d.show();
1340                ensureBootCompleted();
1341            } break;
1342            case UPDATE_CONFIGURATION_MSG: {
1343                final ContentResolver resolver = mContext.getContentResolver();
1344                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1345            } break;
1346            case GC_BACKGROUND_PROCESSES_MSG: {
1347                synchronized (ActivityManagerService.this) {
1348                    performAppGcsIfAppropriateLocked();
1349                }
1350            } break;
1351            case WAIT_FOR_DEBUGGER_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    ProcessRecord app = (ProcessRecord)msg.obj;
1354                    if (msg.arg1 != 0) {
1355                        if (!app.waitedForDebugger) {
1356                            Dialog d = new AppWaitingForDebuggerDialog(
1357                                    ActivityManagerService.this,
1358                                    mContext, app);
1359                            app.waitDialog = d;
1360                            app.waitedForDebugger = true;
1361                            d.show();
1362                        }
1363                    } else {
1364                        if (app.waitDialog != null) {
1365                            app.waitDialog.dismiss();
1366                            app.waitDialog = null;
1367                        }
1368                    }
1369                }
1370            } break;
1371            case SERVICE_TIMEOUT_MSG: {
1372                if (mDidDexOpt) {
1373                    mDidDexOpt = false;
1374                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1375                    nmsg.obj = msg.obj;
1376                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1377                    return;
1378                }
1379                mServices.serviceTimeout((ProcessRecord)msg.obj);
1380            } break;
1381            case UPDATE_TIME_ZONE: {
1382                synchronized (ActivityManagerService.this) {
1383                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1384                        ProcessRecord r = mLruProcesses.get(i);
1385                        if (r.thread != null) {
1386                            try {
1387                                r.thread.updateTimeZone();
1388                            } catch (RemoteException ex) {
1389                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case CLEAR_DNS_CACHE_MSG: {
1396                synchronized (ActivityManagerService.this) {
1397                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1398                        ProcessRecord r = mLruProcesses.get(i);
1399                        if (r.thread != null) {
1400                            try {
1401                                r.thread.clearDnsCache();
1402                            } catch (RemoteException ex) {
1403                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1404                            }
1405                        }
1406                    }
1407                }
1408            } break;
1409            case UPDATE_HTTP_PROXY_MSG: {
1410                ProxyInfo proxy = (ProxyInfo)msg.obj;
1411                String host = "";
1412                String port = "";
1413                String exclList = "";
1414                Uri pacFileUrl = Uri.EMPTY;
1415                if (proxy != null) {
1416                    host = proxy.getHost();
1417                    port = Integer.toString(proxy.getPort());
1418                    exclList = proxy.getExclusionListAsString();
1419                    pacFileUrl = proxy.getPacFileUrl();
1420                }
1421                synchronized (ActivityManagerService.this) {
1422                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1423                        ProcessRecord r = mLruProcesses.get(i);
1424                        if (r.thread != null) {
1425                            try {
1426                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1427                            } catch (RemoteException ex) {
1428                                Slog.w(TAG, "Failed to update http proxy for: " +
1429                                        r.info.processName);
1430                            }
1431                        }
1432                    }
1433                }
1434            } break;
1435            case SHOW_UID_ERROR_MSG: {
1436                String title = "System UIDs Inconsistent";
1437                String text = "UIDs on the system are inconsistent, you need to wipe your"
1438                        + " data partition or your device will be unstable.";
1439                Log.e(TAG, title + ": " + text);
1440                if (mShowDialogs) {
1441                    // XXX This is a temporary dialog, no need to localize.
1442                    AlertDialog d = new BaseErrorDialog(mContext);
1443                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1444                    d.setCancelable(false);
1445                    d.setTitle(title);
1446                    d.setMessage(text);
1447                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1448                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1449                    mUidAlert = d;
1450                    d.show();
1451                }
1452            } break;
1453            case IM_FEELING_LUCKY_MSG: {
1454                if (mUidAlert != null) {
1455                    mUidAlert.dismiss();
1456                    mUidAlert = null;
1457                }
1458            } break;
1459            case PROC_START_TIMEOUT_MSG: {
1460                if (mDidDexOpt) {
1461                    mDidDexOpt = false;
1462                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1463                    nmsg.obj = msg.obj;
1464                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1465                    return;
1466                }
1467                ProcessRecord app = (ProcessRecord)msg.obj;
1468                synchronized (ActivityManagerService.this) {
1469                    processStartTimedOutLocked(app);
1470                }
1471            } break;
1472            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1473                synchronized (ActivityManagerService.this) {
1474                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1475                }
1476            } break;
1477            case KILL_APPLICATION_MSG: {
1478                synchronized (ActivityManagerService.this) {
1479                    int appid = msg.arg1;
1480                    boolean restart = (msg.arg2 == 1);
1481                    Bundle bundle = (Bundle)msg.obj;
1482                    String pkg = bundle.getString("pkg");
1483                    String reason = bundle.getString("reason");
1484                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1485                            false, UserHandle.USER_ALL, reason);
1486                }
1487            } break;
1488            case FINALIZE_PENDING_INTENT_MSG: {
1489                ((PendingIntentRecord)msg.obj).completeFinalize();
1490            } break;
1491            case POST_HEAVY_NOTIFICATION_MSG: {
1492                INotificationManager inm = NotificationManager.getService();
1493                if (inm == null) {
1494                    return;
1495                }
1496
1497                ActivityRecord root = (ActivityRecord)msg.obj;
1498                ProcessRecord process = root.app;
1499                if (process == null) {
1500                    return;
1501                }
1502
1503                try {
1504                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1505                    String text = mContext.getString(R.string.heavy_weight_notification,
1506                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1507                    Notification notification = new Notification();
1508                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1509                    notification.when = 0;
1510                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1511                    notification.tickerText = text;
1512                    notification.defaults = 0; // please be quiet
1513                    notification.sound = null;
1514                    notification.vibrate = null;
1515                    notification.color = mContext.getResources().getColor(
1516                            com.android.internal.R.color.system_notification_accent_color);
1517                    notification.setLatestEventInfo(context, text,
1518                            mContext.getText(R.string.heavy_weight_notification_detail),
1519                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1520                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1521                                    new UserHandle(root.userId)));
1522
1523                    try {
1524                        int[] outId = new int[1];
1525                        inm.enqueueNotificationWithTag("android", "android", null,
1526                                R.string.heavy_weight_notification,
1527                                notification, outId, root.userId);
1528                    } catch (RuntimeException e) {
1529                        Slog.w(ActivityManagerService.TAG,
1530                                "Error showing notification for heavy-weight app", e);
1531                    } catch (RemoteException e) {
1532                    }
1533                } catch (NameNotFoundException e) {
1534                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1535                }
1536            } break;
1537            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1538                INotificationManager inm = NotificationManager.getService();
1539                if (inm == null) {
1540                    return;
1541                }
1542                try {
1543                    inm.cancelNotificationWithTag("android", null,
1544                            R.string.heavy_weight_notification,  msg.arg1);
1545                } catch (RuntimeException e) {
1546                    Slog.w(ActivityManagerService.TAG,
1547                            "Error canceling notification for service", e);
1548                } catch (RemoteException e) {
1549                }
1550            } break;
1551            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1552                synchronized (ActivityManagerService.this) {
1553                    checkExcessivePowerUsageLocked(true);
1554                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1555                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1556                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1557                }
1558            } break;
1559            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    ActivityRecord ar = (ActivityRecord)msg.obj;
1562                    if (mCompatModeDialog != null) {
1563                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1564                                ar.info.applicationInfo.packageName)) {
1565                            return;
1566                        }
1567                        mCompatModeDialog.dismiss();
1568                        mCompatModeDialog = null;
1569                    }
1570                    if (ar != null && false) {
1571                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1572                                ar.packageName)) {
1573                            int mode = mCompatModePackages.computeCompatModeLocked(
1574                                    ar.info.applicationInfo);
1575                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1576                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1577                                mCompatModeDialog = new CompatModeDialog(
1578                                        ActivityManagerService.this, mContext,
1579                                        ar.info.applicationInfo);
1580                                mCompatModeDialog.show();
1581                            }
1582                        }
1583                    }
1584                }
1585                break;
1586            }
1587            case DISPATCH_PROCESSES_CHANGED: {
1588                dispatchProcessesChanged();
1589                break;
1590            }
1591            case DISPATCH_PROCESS_DIED: {
1592                final int pid = msg.arg1;
1593                final int uid = msg.arg2;
1594                dispatchProcessDied(pid, uid);
1595                break;
1596            }
1597            case REPORT_MEM_USAGE_MSG: {
1598                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1599                Thread thread = new Thread() {
1600                    @Override public void run() {
1601                        final SparseArray<ProcessMemInfo> infoMap
1602                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1603                        for (int i=0, N=memInfos.size(); i<N; i++) {
1604                            ProcessMemInfo mi = memInfos.get(i);
1605                            infoMap.put(mi.pid, mi);
1606                        }
1607                        updateCpuStatsNow();
1608                        synchronized (mProcessCpuTracker) {
1609                            final int N = mProcessCpuTracker.countStats();
1610                            for (int i=0; i<N; i++) {
1611                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1612                                if (st.vsize > 0) {
1613                                    long pss = Debug.getPss(st.pid, null);
1614                                    if (pss > 0) {
1615                                        if (infoMap.indexOfKey(st.pid) < 0) {
1616                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1617                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1618                                            mi.pss = pss;
1619                                            memInfos.add(mi);
1620                                        }
1621                                    }
1622                                }
1623                            }
1624                        }
1625
1626                        long totalPss = 0;
1627                        for (int i=0, N=memInfos.size(); i<N; i++) {
1628                            ProcessMemInfo mi = memInfos.get(i);
1629                            if (mi.pss == 0) {
1630                                mi.pss = Debug.getPss(mi.pid, null);
1631                            }
1632                            totalPss += mi.pss;
1633                        }
1634                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1635                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1636                                if (lhs.oomAdj != rhs.oomAdj) {
1637                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1638                                }
1639                                if (lhs.pss != rhs.pss) {
1640                                    return lhs.pss < rhs.pss ? 1 : -1;
1641                                }
1642                                return 0;
1643                            }
1644                        });
1645
1646                        StringBuilder tag = new StringBuilder(128);
1647                        StringBuilder stack = new StringBuilder(128);
1648                        tag.append("Low on memory -- ");
1649                        appendMemBucket(tag, totalPss, "total", false);
1650                        appendMemBucket(stack, totalPss, "total", true);
1651
1652                        StringBuilder logBuilder = new StringBuilder(1024);
1653                        logBuilder.append("Low on memory:\n");
1654
1655                        boolean firstLine = true;
1656                        int lastOomAdj = Integer.MIN_VALUE;
1657                        for (int i=0, N=memInfos.size(); i<N; i++) {
1658                            ProcessMemInfo mi = memInfos.get(i);
1659
1660                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1661                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1662                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1663                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1664                                if (lastOomAdj != mi.oomAdj) {
1665                                    lastOomAdj = mi.oomAdj;
1666                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1667                                        tag.append(" / ");
1668                                    }
1669                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1670                                        if (firstLine) {
1671                                            stack.append(":");
1672                                            firstLine = false;
1673                                        }
1674                                        stack.append("\n\t at ");
1675                                    } else {
1676                                        stack.append("$");
1677                                    }
1678                                } else {
1679                                    tag.append(" ");
1680                                    stack.append("$");
1681                                }
1682                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1683                                    appendMemBucket(tag, mi.pss, mi.name, false);
1684                                }
1685                                appendMemBucket(stack, mi.pss, mi.name, true);
1686                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1687                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1688                                    stack.append("(");
1689                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1690                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1691                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1692                                            stack.append(":");
1693                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1694                                        }
1695                                    }
1696                                    stack.append(")");
1697                                }
1698                            }
1699
1700                            logBuilder.append("  ");
1701                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1702                            logBuilder.append(' ');
1703                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1704                            logBuilder.append(' ');
1705                            ProcessList.appendRamKb(logBuilder, mi.pss);
1706                            logBuilder.append(" kB: ");
1707                            logBuilder.append(mi.name);
1708                            logBuilder.append(" (");
1709                            logBuilder.append(mi.pid);
1710                            logBuilder.append(") ");
1711                            logBuilder.append(mi.adjType);
1712                            logBuilder.append('\n');
1713                            if (mi.adjReason != null) {
1714                                logBuilder.append("                      ");
1715                                logBuilder.append(mi.adjReason);
1716                                logBuilder.append('\n');
1717                            }
1718                        }
1719
1720                        logBuilder.append("           ");
1721                        ProcessList.appendRamKb(logBuilder, totalPss);
1722                        logBuilder.append(" kB: TOTAL\n");
1723
1724                        long[] infos = new long[Debug.MEMINFO_COUNT];
1725                        Debug.getMemInfo(infos);
1726                        logBuilder.append("  MemInfo: ");
1727                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1728                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1729                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1730                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1731                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1732                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1733                            logBuilder.append("  ZRAM: ");
1734                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1735                            logBuilder.append(" kB RAM, ");
1736                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1737                            logBuilder.append(" kB swap total, ");
1738                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1739                            logBuilder.append(" kB swap free\n");
1740                        }
1741                        Slog.i(TAG, logBuilder.toString());
1742
1743                        StringBuilder dropBuilder = new StringBuilder(1024);
1744                        /*
1745                        StringWriter oomSw = new StringWriter();
1746                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1747                        StringWriter catSw = new StringWriter();
1748                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1749                        String[] emptyArgs = new String[] { };
1750                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1751                        oomPw.flush();
1752                        String oomString = oomSw.toString();
1753                        */
1754                        dropBuilder.append(stack);
1755                        dropBuilder.append('\n');
1756                        dropBuilder.append('\n');
1757                        dropBuilder.append(logBuilder);
1758                        dropBuilder.append('\n');
1759                        /*
1760                        dropBuilder.append(oomString);
1761                        dropBuilder.append('\n');
1762                        */
1763                        StringWriter catSw = new StringWriter();
1764                        synchronized (ActivityManagerService.this) {
1765                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1766                            String[] emptyArgs = new String[] { };
1767                            catPw.println();
1768                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1769                            catPw.println();
1770                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1771                                    false, false, null);
1772                            catPw.println();
1773                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1774                            catPw.flush();
1775                        }
1776                        dropBuilder.append(catSw.toString());
1777                        addErrorToDropBox("lowmem", null, "system_server", null,
1778                                null, tag.toString(), dropBuilder.toString(), null, null);
1779                        //Slog.i(TAG, "Sent to dropbox:");
1780                        //Slog.i(TAG, dropBuilder.toString());
1781                        synchronized (ActivityManagerService.this) {
1782                            long now = SystemClock.uptimeMillis();
1783                            if (mLastMemUsageReportTime < now) {
1784                                mLastMemUsageReportTime = now;
1785                            }
1786                        }
1787                    }
1788                };
1789                thread.start();
1790                break;
1791            }
1792            case START_USER_SWITCH_MSG: {
1793                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1794                break;
1795            }
1796            case REPORT_USER_SWITCH_MSG: {
1797                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1798                break;
1799            }
1800            case CONTINUE_USER_SWITCH_MSG: {
1801                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1802                break;
1803            }
1804            case USER_SWITCH_TIMEOUT_MSG: {
1805                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1806                break;
1807            }
1808            case IMMERSIVE_MODE_LOCK_MSG: {
1809                final boolean nextState = (msg.arg1 != 0);
1810                if (mUpdateLock.isHeld() != nextState) {
1811                    if (DEBUG_IMMERSIVE) {
1812                        final ActivityRecord r = (ActivityRecord) msg.obj;
1813                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1814                    }
1815                    if (nextState) {
1816                        mUpdateLock.acquire();
1817                    } else {
1818                        mUpdateLock.release();
1819                    }
1820                }
1821                break;
1822            }
1823            case PERSIST_URI_GRANTS_MSG: {
1824                writeGrantedUriPermissions();
1825                break;
1826            }
1827            case REQUEST_ALL_PSS_MSG: {
1828                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1829                break;
1830            }
1831            case START_PROFILES_MSG: {
1832                synchronized (ActivityManagerService.this) {
1833                    startProfilesLocked();
1834                }
1835                break;
1836            }
1837            case UPDATE_TIME: {
1838                synchronized (ActivityManagerService.this) {
1839                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1840                        ProcessRecord r = mLruProcesses.get(i);
1841                        if (r.thread != null) {
1842                            try {
1843                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1844                            } catch (RemoteException ex) {
1845                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1846                            }
1847                        }
1848                    }
1849                }
1850                break;
1851            }
1852            case SYSTEM_USER_START_MSG: {
1853                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1854                        Integer.toString(msg.arg1), msg.arg1);
1855                mSystemServiceManager.startUser(msg.arg1);
1856                break;
1857            }
1858            case SYSTEM_USER_CURRENT_MSG: {
1859                mBatteryStatsService.noteEvent(
1860                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1861                        Integer.toString(msg.arg2), msg.arg2);
1862                mBatteryStatsService.noteEvent(
1863                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1864                        Integer.toString(msg.arg1), msg.arg1);
1865                mSystemServiceManager.switchUser(msg.arg1);
1866                mLockToAppRequest.clearPrompt();
1867                break;
1868            }
1869            case ENTER_ANIMATION_COMPLETE_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1872                    if (r != null && r.app != null && r.app.thread != null) {
1873                        try {
1874                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1875                        } catch (RemoteException e) {
1876                        }
1877                    }
1878                }
1879                break;
1880            }
1881            case FINISH_BOOTING_MSG: {
1882                if (msg.arg1 != 0) {
1883                    finishBooting();
1884                }
1885                if (msg.arg2 != 0) {
1886                    enableScreenAfterBoot();
1887                }
1888                break;
1889            }
1890            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1891                try {
1892                    Locale l = (Locale) msg.obj;
1893                    IBinder service = ServiceManager.getService("mount");
1894                    IMountService mountService = IMountService.Stub.asInterface(service);
1895                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1896                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1897                } catch (RemoteException e) {
1898                    Log.e(TAG, "Error storing locale for decryption UI", e);
1899                }
1900                break;
1901            }
1902            }
1903        }
1904    };
1905
1906    static final int COLLECT_PSS_BG_MSG = 1;
1907
1908    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1909        @Override
1910        public void handleMessage(Message msg) {
1911            switch (msg.what) {
1912            case COLLECT_PSS_BG_MSG: {
1913                long start = SystemClock.uptimeMillis();
1914                MemInfoReader memInfo = null;
1915                synchronized (ActivityManagerService.this) {
1916                    if (mFullPssPending) {
1917                        mFullPssPending = false;
1918                        memInfo = new MemInfoReader();
1919                    }
1920                }
1921                if (memInfo != null) {
1922                    updateCpuStatsNow();
1923                    long nativeTotalPss = 0;
1924                    synchronized (mProcessCpuTracker) {
1925                        final int N = mProcessCpuTracker.countStats();
1926                        for (int j=0; j<N; j++) {
1927                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1928                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1929                                // This is definitely an application process; skip it.
1930                                continue;
1931                            }
1932                            synchronized (mPidsSelfLocked) {
1933                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1934                                    // This is one of our own processes; skip it.
1935                                    continue;
1936                                }
1937                            }
1938                            nativeTotalPss += Debug.getPss(st.pid, null);
1939                        }
1940                    }
1941                    memInfo.readMemInfo();
1942                    synchronized (ActivityManagerService.this) {
1943                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1944                                + (SystemClock.uptimeMillis()-start) + "ms");
1945                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1946                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1947                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1948                                        +memInfo.getSlabSizeKb(),
1949                                nativeTotalPss);
1950                    }
1951                }
1952
1953                int i=0, num=0;
1954                long[] tmp = new long[1];
1955                do {
1956                    ProcessRecord proc;
1957                    int procState;
1958                    int pid;
1959                    synchronized (ActivityManagerService.this) {
1960                        if (i >= mPendingPssProcesses.size()) {
1961                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1962                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1963                            mPendingPssProcesses.clear();
1964                            return;
1965                        }
1966                        proc = mPendingPssProcesses.get(i);
1967                        procState = proc.pssProcState;
1968                        if (proc.thread != null && procState == proc.setProcState) {
1969                            pid = proc.pid;
1970                        } else {
1971                            proc = null;
1972                            pid = 0;
1973                        }
1974                        i++;
1975                    }
1976                    if (proc != null) {
1977                        long pss = Debug.getPss(pid, tmp);
1978                        synchronized (ActivityManagerService.this) {
1979                            if (proc.thread != null && proc.setProcState == procState
1980                                    && proc.pid == pid) {
1981                                num++;
1982                                proc.lastPssTime = SystemClock.uptimeMillis();
1983                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1984                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1985                                        + ": " + pss + " lastPss=" + proc.lastPss
1986                                        + " state=" + ProcessList.makeProcStateString(procState));
1987                                if (proc.initialIdlePss == 0) {
1988                                    proc.initialIdlePss = pss;
1989                                }
1990                                proc.lastPss = pss;
1991                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1992                                    proc.lastCachedPss = pss;
1993                                }
1994                            }
1995                        }
1996                    }
1997                } while (true);
1998            }
1999            }
2000        }
2001    };
2002
2003    /**
2004     * Monitor for package changes and update our internal state.
2005     */
2006    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2007        @Override
2008        public void onPackageRemoved(String packageName, int uid) {
2009            // Remove all tasks with activities in the specified package from the list of recent tasks
2010            final int eventUserId = getChangingUserId();
2011            synchronized (ActivityManagerService.this) {
2012                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2013                    TaskRecord tr = mRecentTasks.get(i);
2014                    if (tr.userId != eventUserId) continue;
2015
2016                    ComponentName cn = tr.intent.getComponent();
2017                    if (cn != null && cn.getPackageName().equals(packageName)) {
2018                        // If the package name matches, remove the task and kill the process
2019                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2020                    }
2021                }
2022            }
2023        }
2024
2025        @Override
2026        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2027            onPackageModified(packageName);
2028            return true;
2029        }
2030
2031        @Override
2032        public void onPackageModified(String packageName) {
2033            final int eventUserId = getChangingUserId();
2034            final PackageManager pm = mContext.getPackageManager();
2035            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2036                    new ArrayList<Pair<Intent, Integer>>();
2037            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2038            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2039            // Copy the list of recent tasks so that we don't hold onto the lock on
2040            // ActivityManagerService for long periods while checking if components exist.
2041            synchronized (ActivityManagerService.this) {
2042                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2043                    TaskRecord tr = mRecentTasks.get(i);
2044                    if (tr.userId != eventUserId) continue;
2045
2046                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2047                }
2048            }
2049            // Check the recent tasks and filter out all tasks with components that no longer exist.
2050            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2051                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2052                ComponentName cn = p.first.getComponent();
2053                if (cn != null && cn.getPackageName().equals(packageName)) {
2054                    if (componentsKnownToExist.contains(cn)) {
2055                        // If we know that the component still exists in the package, then skip
2056                        continue;
2057                    }
2058                    try {
2059                        ActivityInfo info = pm.getActivityInfo(cn, eventUserId);
2060                        if (info != null && info.isEnabled()) {
2061                            componentsKnownToExist.add(cn);
2062                        } else {
2063                            tasksToRemove.add(p.second);
2064                        }
2065                    } catch (Exception e) {}
2066                }
2067            }
2068            // Prune all the tasks with removed components from the list of recent tasks
2069            synchronized (ActivityManagerService.this) {
2070                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2071                    // Remove the task but don't kill the process (since other components in that
2072                    // package may still be running and in the background)
2073                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2074                }
2075            }
2076        }
2077
2078        @Override
2079        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2080            // Force stop the specified packages
2081            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2082            if (packages != null) {
2083                for (String pkg : packages) {
2084                    synchronized (ActivityManagerService.this) {
2085                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2086                                userId, "finished booting")) {
2087                            return true;
2088                        }
2089                    }
2090                }
2091            }
2092            return false;
2093        }
2094    };
2095
2096    public void setSystemProcess() {
2097        try {
2098            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2099            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2100            ServiceManager.addService("meminfo", new MemBinder(this));
2101            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2102            ServiceManager.addService("dbinfo", new DbBinder(this));
2103            if (MONITOR_CPU_USAGE) {
2104                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2105            }
2106            ServiceManager.addService("permission", new PermissionController(this));
2107
2108            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2109                    "android", STOCK_PM_FLAGS);
2110            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2111
2112            synchronized (this) {
2113                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2114                app.persistent = true;
2115                app.pid = MY_PID;
2116                app.maxAdj = ProcessList.SYSTEM_ADJ;
2117                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2118                mProcessNames.put(app.processName, app.uid, app);
2119                synchronized (mPidsSelfLocked) {
2120                    mPidsSelfLocked.put(app.pid, app);
2121                }
2122                updateLruProcessLocked(app, false, null);
2123                updateOomAdjLocked();
2124            }
2125        } catch (PackageManager.NameNotFoundException e) {
2126            throw new RuntimeException(
2127                    "Unable to find android system package", e);
2128        }
2129    }
2130
2131    public void setWindowManager(WindowManagerService wm) {
2132        mWindowManager = wm;
2133        mStackSupervisor.setWindowManager(wm);
2134    }
2135
2136    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2137        mUsageStatsService = usageStatsManager;
2138    }
2139
2140    public void startObservingNativeCrashes() {
2141        final NativeCrashListener ncl = new NativeCrashListener(this);
2142        ncl.start();
2143    }
2144
2145    public IAppOpsService getAppOpsService() {
2146        return mAppOpsService;
2147    }
2148
2149    static class MemBinder extends Binder {
2150        ActivityManagerService mActivityManagerService;
2151        MemBinder(ActivityManagerService activityManagerService) {
2152            mActivityManagerService = activityManagerService;
2153        }
2154
2155        @Override
2156        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2157            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2158                    != PackageManager.PERMISSION_GRANTED) {
2159                pw.println("Permission Denial: can't dump meminfo from from pid="
2160                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2161                        + " without permission " + android.Manifest.permission.DUMP);
2162                return;
2163            }
2164
2165            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2166        }
2167    }
2168
2169    static class GraphicsBinder extends Binder {
2170        ActivityManagerService mActivityManagerService;
2171        GraphicsBinder(ActivityManagerService activityManagerService) {
2172            mActivityManagerService = activityManagerService;
2173        }
2174
2175        @Override
2176        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2177            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2178                    != PackageManager.PERMISSION_GRANTED) {
2179                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2180                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2181                        + " without permission " + android.Manifest.permission.DUMP);
2182                return;
2183            }
2184
2185            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2186        }
2187    }
2188
2189    static class DbBinder extends Binder {
2190        ActivityManagerService mActivityManagerService;
2191        DbBinder(ActivityManagerService activityManagerService) {
2192            mActivityManagerService = activityManagerService;
2193        }
2194
2195        @Override
2196        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2197            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2198                    != PackageManager.PERMISSION_GRANTED) {
2199                pw.println("Permission Denial: can't dump dbinfo from from pid="
2200                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2201                        + " without permission " + android.Manifest.permission.DUMP);
2202                return;
2203            }
2204
2205            mActivityManagerService.dumpDbInfo(fd, pw, args);
2206        }
2207    }
2208
2209    static class CpuBinder extends Binder {
2210        ActivityManagerService mActivityManagerService;
2211        CpuBinder(ActivityManagerService activityManagerService) {
2212            mActivityManagerService = activityManagerService;
2213        }
2214
2215        @Override
2216        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2217            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2218                    != PackageManager.PERMISSION_GRANTED) {
2219                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2220                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2221                        + " without permission " + android.Manifest.permission.DUMP);
2222                return;
2223            }
2224
2225            synchronized (mActivityManagerService.mProcessCpuTracker) {
2226                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2227                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2228                        SystemClock.uptimeMillis()));
2229            }
2230        }
2231    }
2232
2233    public static final class Lifecycle extends SystemService {
2234        private final ActivityManagerService mService;
2235
2236        public Lifecycle(Context context) {
2237            super(context);
2238            mService = new ActivityManagerService(context);
2239        }
2240
2241        @Override
2242        public void onStart() {
2243            mService.start();
2244        }
2245
2246        public ActivityManagerService getService() {
2247            return mService;
2248        }
2249    }
2250
2251    // Note: This method is invoked on the main thread but may need to attach various
2252    // handlers to other threads.  So take care to be explicit about the looper.
2253    public ActivityManagerService(Context systemContext) {
2254        mContext = systemContext;
2255        mFactoryTest = FactoryTest.getMode();
2256        mSystemThread = ActivityThread.currentActivityThread();
2257
2258        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2259
2260        mHandlerThread = new ServiceThread(TAG,
2261                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2262        mHandlerThread.start();
2263        mHandler = new MainHandler(mHandlerThread.getLooper());
2264
2265        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2266                "foreground", BROADCAST_FG_TIMEOUT, false);
2267        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2268                "background", BROADCAST_BG_TIMEOUT, true);
2269        mBroadcastQueues[0] = mFgBroadcastQueue;
2270        mBroadcastQueues[1] = mBgBroadcastQueue;
2271
2272        mServices = new ActiveServices(this);
2273        mProviderMap = new ProviderMap(this);
2274
2275        // TODO: Move creation of battery stats service outside of activity manager service.
2276        File dataDir = Environment.getDataDirectory();
2277        File systemDir = new File(dataDir, "system");
2278        systemDir.mkdirs();
2279        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2280        mBatteryStatsService.getActiveStatistics().readLocked();
2281        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2282        mOnBattery = DEBUG_POWER ? true
2283                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2284        mBatteryStatsService.getActiveStatistics().setCallback(this);
2285
2286        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2287
2288        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2289
2290        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2291
2292        // User 0 is the first and only user that runs at boot.
2293        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2294        mUserLru.add(Integer.valueOf(0));
2295        updateStartedUserArrayLocked();
2296
2297        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2298            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2299
2300        mConfiguration.setToDefaults();
2301        mConfiguration.setLocale(Locale.getDefault());
2302
2303        mConfigurationSeq = mConfiguration.seq = 1;
2304        mProcessCpuTracker.init();
2305
2306        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2307        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2308        mStackSupervisor = new ActivityStackSupervisor(this);
2309        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2310
2311        mProcessCpuThread = new Thread("CpuTracker") {
2312            @Override
2313            public void run() {
2314                while (true) {
2315                    try {
2316                        try {
2317                            synchronized(this) {
2318                                final long now = SystemClock.uptimeMillis();
2319                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2320                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2321                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2322                                //        + ", write delay=" + nextWriteDelay);
2323                                if (nextWriteDelay < nextCpuDelay) {
2324                                    nextCpuDelay = nextWriteDelay;
2325                                }
2326                                if (nextCpuDelay > 0) {
2327                                    mProcessCpuMutexFree.set(true);
2328                                    this.wait(nextCpuDelay);
2329                                }
2330                            }
2331                        } catch (InterruptedException e) {
2332                        }
2333                        updateCpuStatsNow();
2334                    } catch (Exception e) {
2335                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2336                    }
2337                }
2338            }
2339        };
2340
2341        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2342
2343        Watchdog.getInstance().addMonitor(this);
2344        Watchdog.getInstance().addThread(mHandler);
2345    }
2346
2347    public void setSystemServiceManager(SystemServiceManager mgr) {
2348        mSystemServiceManager = mgr;
2349    }
2350
2351    private void start() {
2352        Process.removeAllProcessGroups();
2353        mProcessCpuThread.start();
2354
2355        mBatteryStatsService.publish(mContext);
2356        mAppOpsService.publish(mContext);
2357        Slog.d("AppOps", "AppOpsService published");
2358        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2359    }
2360
2361    public void initPowerManagement() {
2362        mStackSupervisor.initPowerManagement();
2363        mBatteryStatsService.initPowerManagement();
2364    }
2365
2366    @Override
2367    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2368            throws RemoteException {
2369        if (code == SYSPROPS_TRANSACTION) {
2370            // We need to tell all apps about the system property change.
2371            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2372            synchronized(this) {
2373                final int NP = mProcessNames.getMap().size();
2374                for (int ip=0; ip<NP; ip++) {
2375                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2376                    final int NA = apps.size();
2377                    for (int ia=0; ia<NA; ia++) {
2378                        ProcessRecord app = apps.valueAt(ia);
2379                        if (app.thread != null) {
2380                            procs.add(app.thread.asBinder());
2381                        }
2382                    }
2383                }
2384            }
2385
2386            int N = procs.size();
2387            for (int i=0; i<N; i++) {
2388                Parcel data2 = Parcel.obtain();
2389                try {
2390                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2391                } catch (RemoteException e) {
2392                }
2393                data2.recycle();
2394            }
2395        }
2396        try {
2397            return super.onTransact(code, data, reply, flags);
2398        } catch (RuntimeException e) {
2399            // The activity manager only throws security exceptions, so let's
2400            // log all others.
2401            if (!(e instanceof SecurityException)) {
2402                Slog.wtf(TAG, "Activity Manager Crash", e);
2403            }
2404            throw e;
2405        }
2406    }
2407
2408    void updateCpuStats() {
2409        final long now = SystemClock.uptimeMillis();
2410        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2411            return;
2412        }
2413        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2414            synchronized (mProcessCpuThread) {
2415                mProcessCpuThread.notify();
2416            }
2417        }
2418    }
2419
2420    void updateCpuStatsNow() {
2421        synchronized (mProcessCpuTracker) {
2422            mProcessCpuMutexFree.set(false);
2423            final long now = SystemClock.uptimeMillis();
2424            boolean haveNewCpuStats = false;
2425
2426            if (MONITOR_CPU_USAGE &&
2427                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2428                mLastCpuTime.set(now);
2429                haveNewCpuStats = true;
2430                mProcessCpuTracker.update();
2431                //Slog.i(TAG, mProcessCpu.printCurrentState());
2432                //Slog.i(TAG, "Total CPU usage: "
2433                //        + mProcessCpu.getTotalCpuPercent() + "%");
2434
2435                // Slog the cpu usage if the property is set.
2436                if ("true".equals(SystemProperties.get("events.cpu"))) {
2437                    int user = mProcessCpuTracker.getLastUserTime();
2438                    int system = mProcessCpuTracker.getLastSystemTime();
2439                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2440                    int irq = mProcessCpuTracker.getLastIrqTime();
2441                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2442                    int idle = mProcessCpuTracker.getLastIdleTime();
2443
2444                    int total = user + system + iowait + irq + softIrq + idle;
2445                    if (total == 0) total = 1;
2446
2447                    EventLog.writeEvent(EventLogTags.CPU,
2448                            ((user+system+iowait+irq+softIrq) * 100) / total,
2449                            (user * 100) / total,
2450                            (system * 100) / total,
2451                            (iowait * 100) / total,
2452                            (irq * 100) / total,
2453                            (softIrq * 100) / total);
2454                }
2455            }
2456
2457            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2458            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2459            synchronized(bstats) {
2460                synchronized(mPidsSelfLocked) {
2461                    if (haveNewCpuStats) {
2462                        if (mOnBattery) {
2463                            int perc = bstats.startAddingCpuLocked();
2464                            int totalUTime = 0;
2465                            int totalSTime = 0;
2466                            final int N = mProcessCpuTracker.countStats();
2467                            for (int i=0; i<N; i++) {
2468                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2469                                if (!st.working) {
2470                                    continue;
2471                                }
2472                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2473                                int otherUTime = (st.rel_utime*perc)/100;
2474                                int otherSTime = (st.rel_stime*perc)/100;
2475                                totalUTime += otherUTime;
2476                                totalSTime += otherSTime;
2477                                if (pr != null) {
2478                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2479                                    if (ps == null || !ps.isActive()) {
2480                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2481                                                pr.info.uid, pr.processName);
2482                                    }
2483                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2484                                            st.rel_stime-otherSTime);
2485                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2486                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2487                                } else {
2488                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2489                                    if (ps == null || !ps.isActive()) {
2490                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2491                                                bstats.mapUid(st.uid), st.name);
2492                                    }
2493                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2494                                            st.rel_stime-otherSTime);
2495                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2496                                }
2497                            }
2498                            bstats.finishAddingCpuLocked(perc, totalUTime,
2499                                    totalSTime, cpuSpeedTimes);
2500                        }
2501                    }
2502                }
2503
2504                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2505                    mLastWriteTime = now;
2506                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2507                }
2508            }
2509        }
2510    }
2511
2512    @Override
2513    public void batteryNeedsCpuUpdate() {
2514        updateCpuStatsNow();
2515    }
2516
2517    @Override
2518    public void batteryPowerChanged(boolean onBattery) {
2519        // When plugging in, update the CPU stats first before changing
2520        // the plug state.
2521        updateCpuStatsNow();
2522        synchronized (this) {
2523            synchronized(mPidsSelfLocked) {
2524                mOnBattery = DEBUG_POWER ? true : onBattery;
2525            }
2526        }
2527    }
2528
2529    /**
2530     * Initialize the application bind args. These are passed to each
2531     * process when the bindApplication() IPC is sent to the process. They're
2532     * lazily setup to make sure the services are running when they're asked for.
2533     */
2534    private HashMap<String, IBinder> getCommonServicesLocked() {
2535        if (mAppBindArgs == null) {
2536            mAppBindArgs = new HashMap<String, IBinder>();
2537
2538            // Setup the application init args
2539            mAppBindArgs.put("package", ServiceManager.getService("package"));
2540            mAppBindArgs.put("window", ServiceManager.getService("window"));
2541            mAppBindArgs.put(Context.ALARM_SERVICE,
2542                    ServiceManager.getService(Context.ALARM_SERVICE));
2543        }
2544        return mAppBindArgs;
2545    }
2546
2547    final void setFocusedActivityLocked(ActivityRecord r) {
2548        if (mFocusedActivity != r) {
2549            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2550            mFocusedActivity = r;
2551            if (r.task != null && r.task.voiceInteractor != null) {
2552                startRunningVoiceLocked();
2553            } else {
2554                finishRunningVoiceLocked();
2555            }
2556            mStackSupervisor.setFocusedStack(r);
2557            if (r != null) {
2558                mWindowManager.setFocusedApp(r.appToken, true);
2559            }
2560            applyUpdateLockStateLocked(r);
2561        }
2562    }
2563
2564    final void clearFocusedActivity(ActivityRecord r) {
2565        if (mFocusedActivity == r) {
2566            mFocusedActivity = null;
2567        }
2568    }
2569
2570    @Override
2571    public void setFocusedStack(int stackId) {
2572        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2573        synchronized (ActivityManagerService.this) {
2574            ActivityStack stack = mStackSupervisor.getStack(stackId);
2575            if (stack != null) {
2576                ActivityRecord r = stack.topRunningActivityLocked(null);
2577                if (r != null) {
2578                    setFocusedActivityLocked(r);
2579                }
2580            }
2581        }
2582    }
2583
2584    @Override
2585    public void notifyActivityDrawn(IBinder token) {
2586        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2587        synchronized (this) {
2588            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2589            if (r != null) {
2590                r.task.stack.notifyActivityDrawnLocked(r);
2591            }
2592        }
2593    }
2594
2595    final void applyUpdateLockStateLocked(ActivityRecord r) {
2596        // Modifications to the UpdateLock state are done on our handler, outside
2597        // the activity manager's locks.  The new state is determined based on the
2598        // state *now* of the relevant activity record.  The object is passed to
2599        // the handler solely for logging detail, not to be consulted/modified.
2600        final boolean nextState = r != null && r.immersive;
2601        mHandler.sendMessage(
2602                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2603    }
2604
2605    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2606        Message msg = Message.obtain();
2607        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2608        msg.obj = r.task.askedCompatMode ? null : r;
2609        mHandler.sendMessage(msg);
2610    }
2611
2612    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2613            String what, Object obj, ProcessRecord srcApp) {
2614        app.lastActivityTime = now;
2615
2616        if (app.activities.size() > 0) {
2617            // Don't want to touch dependent processes that are hosting activities.
2618            return index;
2619        }
2620
2621        int lrui = mLruProcesses.lastIndexOf(app);
2622        if (lrui < 0) {
2623            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2624                    + what + " " + obj + " from " + srcApp);
2625            return index;
2626        }
2627
2628        if (lrui >= index) {
2629            // Don't want to cause this to move dependent processes *back* in the
2630            // list as if they were less frequently used.
2631            return index;
2632        }
2633
2634        if (lrui >= mLruProcessActivityStart) {
2635            // Don't want to touch dependent processes that are hosting activities.
2636            return index;
2637        }
2638
2639        mLruProcesses.remove(lrui);
2640        if (index > 0) {
2641            index--;
2642        }
2643        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2644                + " in LRU list: " + app);
2645        mLruProcesses.add(index, app);
2646        return index;
2647    }
2648
2649    final void removeLruProcessLocked(ProcessRecord app) {
2650        int lrui = mLruProcesses.lastIndexOf(app);
2651        if (lrui >= 0) {
2652            if (!app.killed) {
2653                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2654                Process.killProcessQuiet(app.pid);
2655                Process.killProcessGroup(app.info.uid, app.pid);
2656            }
2657            if (lrui <= mLruProcessActivityStart) {
2658                mLruProcessActivityStart--;
2659            }
2660            if (lrui <= mLruProcessServiceStart) {
2661                mLruProcessServiceStart--;
2662            }
2663            mLruProcesses.remove(lrui);
2664        }
2665    }
2666
2667    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2668            ProcessRecord client) {
2669        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2670                || app.treatLikeActivity;
2671        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2672        if (!activityChange && hasActivity) {
2673            // The process has activities, so we are only allowing activity-based adjustments
2674            // to move it.  It should be kept in the front of the list with other
2675            // processes that have activities, and we don't want those to change their
2676            // order except due to activity operations.
2677            return;
2678        }
2679
2680        mLruSeq++;
2681        final long now = SystemClock.uptimeMillis();
2682        app.lastActivityTime = now;
2683
2684        // First a quick reject: if the app is already at the position we will
2685        // put it, then there is nothing to do.
2686        if (hasActivity) {
2687            final int N = mLruProcesses.size();
2688            if (N > 0 && mLruProcesses.get(N-1) == app) {
2689                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2690                return;
2691            }
2692        } else {
2693            if (mLruProcessServiceStart > 0
2694                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2695                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2696                return;
2697            }
2698        }
2699
2700        int lrui = mLruProcesses.lastIndexOf(app);
2701
2702        if (app.persistent && lrui >= 0) {
2703            // We don't care about the position of persistent processes, as long as
2704            // they are in the list.
2705            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2706            return;
2707        }
2708
2709        /* In progress: compute new position first, so we can avoid doing work
2710           if the process is not actually going to move.  Not yet working.
2711        int addIndex;
2712        int nextIndex;
2713        boolean inActivity = false, inService = false;
2714        if (hasActivity) {
2715            // Process has activities, put it at the very tipsy-top.
2716            addIndex = mLruProcesses.size();
2717            nextIndex = mLruProcessServiceStart;
2718            inActivity = true;
2719        } else if (hasService) {
2720            // Process has services, put it at the top of the service list.
2721            addIndex = mLruProcessActivityStart;
2722            nextIndex = mLruProcessServiceStart;
2723            inActivity = true;
2724            inService = true;
2725        } else  {
2726            // Process not otherwise of interest, it goes to the top of the non-service area.
2727            addIndex = mLruProcessServiceStart;
2728            if (client != null) {
2729                int clientIndex = mLruProcesses.lastIndexOf(client);
2730                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2731                        + app);
2732                if (clientIndex >= 0 && addIndex > clientIndex) {
2733                    addIndex = clientIndex;
2734                }
2735            }
2736            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2737        }
2738
2739        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2740                + mLruProcessActivityStart + "): " + app);
2741        */
2742
2743        if (lrui >= 0) {
2744            if (lrui < mLruProcessActivityStart) {
2745                mLruProcessActivityStart--;
2746            }
2747            if (lrui < mLruProcessServiceStart) {
2748                mLruProcessServiceStart--;
2749            }
2750            /*
2751            if (addIndex > lrui) {
2752                addIndex--;
2753            }
2754            if (nextIndex > lrui) {
2755                nextIndex--;
2756            }
2757            */
2758            mLruProcesses.remove(lrui);
2759        }
2760
2761        /*
2762        mLruProcesses.add(addIndex, app);
2763        if (inActivity) {
2764            mLruProcessActivityStart++;
2765        }
2766        if (inService) {
2767            mLruProcessActivityStart++;
2768        }
2769        */
2770
2771        int nextIndex;
2772        if (hasActivity) {
2773            final int N = mLruProcesses.size();
2774            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2775                // Process doesn't have activities, but has clients with
2776                // activities...  move it up, but one below the top (the top
2777                // should always have a real activity).
2778                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2779                mLruProcesses.add(N-1, app);
2780                // To keep it from spamming the LRU list (by making a bunch of clients),
2781                // we will push down any other entries owned by the app.
2782                final int uid = app.info.uid;
2783                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2784                    ProcessRecord subProc = mLruProcesses.get(i);
2785                    if (subProc.info.uid == uid) {
2786                        // We want to push this one down the list.  If the process after
2787                        // it is for the same uid, however, don't do so, because we don't
2788                        // want them internally to be re-ordered.
2789                        if (mLruProcesses.get(i-1).info.uid != uid) {
2790                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2791                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2792                            ProcessRecord tmp = mLruProcesses.get(i);
2793                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2794                            mLruProcesses.set(i-1, tmp);
2795                            i--;
2796                        }
2797                    } else {
2798                        // A gap, we can stop here.
2799                        break;
2800                    }
2801                }
2802            } else {
2803                // Process has activities, put it at the very tipsy-top.
2804                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2805                mLruProcesses.add(app);
2806            }
2807            nextIndex = mLruProcessServiceStart;
2808        } else if (hasService) {
2809            // Process has services, put it at the top of the service list.
2810            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2811            mLruProcesses.add(mLruProcessActivityStart, app);
2812            nextIndex = mLruProcessServiceStart;
2813            mLruProcessActivityStart++;
2814        } else  {
2815            // Process not otherwise of interest, it goes to the top of the non-service area.
2816            int index = mLruProcessServiceStart;
2817            if (client != null) {
2818                // If there is a client, don't allow the process to be moved up higher
2819                // in the list than that client.
2820                int clientIndex = mLruProcesses.lastIndexOf(client);
2821                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2822                        + " when updating " + app);
2823                if (clientIndex <= lrui) {
2824                    // Don't allow the client index restriction to push it down farther in the
2825                    // list than it already is.
2826                    clientIndex = lrui;
2827                }
2828                if (clientIndex >= 0 && index > clientIndex) {
2829                    index = clientIndex;
2830                }
2831            }
2832            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2833            mLruProcesses.add(index, app);
2834            nextIndex = index-1;
2835            mLruProcessActivityStart++;
2836            mLruProcessServiceStart++;
2837        }
2838
2839        // If the app is currently using a content provider or service,
2840        // bump those processes as well.
2841        for (int j=app.connections.size()-1; j>=0; j--) {
2842            ConnectionRecord cr = app.connections.valueAt(j);
2843            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2844                    && cr.binding.service.app != null
2845                    && cr.binding.service.app.lruSeq != mLruSeq
2846                    && !cr.binding.service.app.persistent) {
2847                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2848                        "service connection", cr, app);
2849            }
2850        }
2851        for (int j=app.conProviders.size()-1; j>=0; j--) {
2852            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2853            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2854                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2855                        "provider reference", cpr, app);
2856            }
2857        }
2858    }
2859
2860    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2861        if (uid == Process.SYSTEM_UID) {
2862            // The system gets to run in any process.  If there are multiple
2863            // processes with the same uid, just pick the first (this
2864            // should never happen).
2865            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2866            if (procs == null) return null;
2867            final int N = procs.size();
2868            for (int i = 0; i < N; i++) {
2869                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2870            }
2871        }
2872        ProcessRecord proc = mProcessNames.get(processName, uid);
2873        if (false && proc != null && !keepIfLarge
2874                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2875                && proc.lastCachedPss >= 4000) {
2876            // Turn this condition on to cause killing to happen regularly, for testing.
2877            if (proc.baseProcessTracker != null) {
2878                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2879            }
2880            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2881        } else if (proc != null && !keepIfLarge
2882                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2883                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2884            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2885            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2886                if (proc.baseProcessTracker != null) {
2887                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2888                }
2889                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2890            }
2891        }
2892        return proc;
2893    }
2894
2895    void ensurePackageDexOpt(String packageName) {
2896        IPackageManager pm = AppGlobals.getPackageManager();
2897        try {
2898            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2899                mDidDexOpt = true;
2900            }
2901        } catch (RemoteException e) {
2902        }
2903    }
2904
2905    boolean isNextTransitionForward() {
2906        int transit = mWindowManager.getPendingAppTransition();
2907        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2908                || transit == AppTransition.TRANSIT_TASK_OPEN
2909                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2910    }
2911
2912    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2913            String processName, String abiOverride, int uid, Runnable crashHandler) {
2914        synchronized(this) {
2915            ApplicationInfo info = new ApplicationInfo();
2916            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2917            // For isolated processes, the former contains the parent's uid and the latter the
2918            // actual uid of the isolated process.
2919            // In the special case introduced by this method (which is, starting an isolated
2920            // process directly from the SystemServer without an actual parent app process) the
2921            // closest thing to a parent's uid is SYSTEM_UID.
2922            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2923            // the |isolated| logic in the ProcessRecord constructor.
2924            info.uid = Process.SYSTEM_UID;
2925            info.processName = processName;
2926            info.className = entryPoint;
2927            info.packageName = "android";
2928            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2929                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2930                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2931                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2932                    crashHandler);
2933            return proc != null ? proc.pid : 0;
2934        }
2935    }
2936
2937    final ProcessRecord startProcessLocked(String processName,
2938            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2939            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2940            boolean isolated, boolean keepIfLarge) {
2941        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2942                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2943                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2944                null /* crashHandler */);
2945    }
2946
2947    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2948            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2949            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2950            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2951        long startTime = SystemClock.elapsedRealtime();
2952        ProcessRecord app;
2953        if (!isolated) {
2954            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2955            checkTime(startTime, "startProcess: after getProcessRecord");
2956        } else {
2957            // If this is an isolated process, it can't re-use an existing process.
2958            app = null;
2959        }
2960        // We don't have to do anything more if:
2961        // (1) There is an existing application record; and
2962        // (2) The caller doesn't think it is dead, OR there is no thread
2963        //     object attached to it so we know it couldn't have crashed; and
2964        // (3) There is a pid assigned to it, so it is either starting or
2965        //     already running.
2966        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2967                + " app=" + app + " knownToBeDead=" + knownToBeDead
2968                + " thread=" + (app != null ? app.thread : null)
2969                + " pid=" + (app != null ? app.pid : -1));
2970        if (app != null && app.pid > 0) {
2971            if (!knownToBeDead || app.thread == null) {
2972                // We already have the app running, or are waiting for it to
2973                // come up (we have a pid but not yet its thread), so keep it.
2974                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2975                // If this is a new package in the process, add the package to the list
2976                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2977                checkTime(startTime, "startProcess: done, added package to proc");
2978                return app;
2979            }
2980
2981            // An application record is attached to a previous process,
2982            // clean it up now.
2983            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2984            checkTime(startTime, "startProcess: bad proc running, killing");
2985            Process.killProcessGroup(app.info.uid, app.pid);
2986            handleAppDiedLocked(app, true, true);
2987            checkTime(startTime, "startProcess: done killing old proc");
2988        }
2989
2990        String hostingNameStr = hostingName != null
2991                ? hostingName.flattenToShortString() : null;
2992
2993        if (!isolated) {
2994            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2995                // If we are in the background, then check to see if this process
2996                // is bad.  If so, we will just silently fail.
2997                if (mBadProcesses.get(info.processName, info.uid) != null) {
2998                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2999                            + "/" + info.processName);
3000                    return null;
3001                }
3002            } else {
3003                // When the user is explicitly starting a process, then clear its
3004                // crash count so that we won't make it bad until they see at
3005                // least one crash dialog again, and make the process good again
3006                // if it had been bad.
3007                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3008                        + "/" + info.processName);
3009                mProcessCrashTimes.remove(info.processName, info.uid);
3010                if (mBadProcesses.get(info.processName, info.uid) != null) {
3011                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3012                            UserHandle.getUserId(info.uid), info.uid,
3013                            info.processName);
3014                    mBadProcesses.remove(info.processName, info.uid);
3015                    if (app != null) {
3016                        app.bad = false;
3017                    }
3018                }
3019            }
3020        }
3021
3022        if (app == null) {
3023            checkTime(startTime, "startProcess: creating new process record");
3024            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3025            app.crashHandler = crashHandler;
3026            if (app == null) {
3027                Slog.w(TAG, "Failed making new process record for "
3028                        + processName + "/" + info.uid + " isolated=" + isolated);
3029                return null;
3030            }
3031            mProcessNames.put(processName, app.uid, app);
3032            if (isolated) {
3033                mIsolatedProcesses.put(app.uid, app);
3034            }
3035            checkTime(startTime, "startProcess: done creating new process record");
3036        } else {
3037            // If this is a new package in the process, add the package to the list
3038            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3039            checkTime(startTime, "startProcess: added package to existing proc");
3040        }
3041
3042        // If the system is not ready yet, then hold off on starting this
3043        // process until it is.
3044        if (!mProcessesReady
3045                && !isAllowedWhileBooting(info)
3046                && !allowWhileBooting) {
3047            if (!mProcessesOnHold.contains(app)) {
3048                mProcessesOnHold.add(app);
3049            }
3050            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3051            checkTime(startTime, "startProcess: returning with proc on hold");
3052            return app;
3053        }
3054
3055        checkTime(startTime, "startProcess: stepping in to startProcess");
3056        startProcessLocked(
3057                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3058        checkTime(startTime, "startProcess: done starting proc!");
3059        return (app.pid != 0) ? app : null;
3060    }
3061
3062    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3063        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3064    }
3065
3066    private final void startProcessLocked(ProcessRecord app,
3067            String hostingType, String hostingNameStr) {
3068        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3069                null /* entryPoint */, null /* entryPointArgs */);
3070    }
3071
3072    private final void startProcessLocked(ProcessRecord app, String hostingType,
3073            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3074        long startTime = SystemClock.elapsedRealtime();
3075        if (app.pid > 0 && app.pid != MY_PID) {
3076            checkTime(startTime, "startProcess: removing from pids map");
3077            synchronized (mPidsSelfLocked) {
3078                mPidsSelfLocked.remove(app.pid);
3079                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3080            }
3081            checkTime(startTime, "startProcess: done removing from pids map");
3082            app.setPid(0);
3083        }
3084
3085        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3086                "startProcessLocked removing on hold: " + app);
3087        mProcessesOnHold.remove(app);
3088
3089        checkTime(startTime, "startProcess: starting to update cpu stats");
3090        updateCpuStats();
3091        checkTime(startTime, "startProcess: done updating cpu stats");
3092
3093        try {
3094            int uid = app.uid;
3095
3096            int[] gids = null;
3097            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3098            if (!app.isolated) {
3099                int[] permGids = null;
3100                try {
3101                    checkTime(startTime, "startProcess: getting gids from package manager");
3102                    final PackageManager pm = mContext.getPackageManager();
3103                    permGids = pm.getPackageGids(app.info.packageName);
3104
3105                    if (Environment.isExternalStorageEmulated()) {
3106                        checkTime(startTime, "startProcess: checking external storage perm");
3107                        if (pm.checkPermission(
3108                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3109                                app.info.packageName) == PERMISSION_GRANTED) {
3110                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3111                        } else {
3112                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3113                        }
3114                    }
3115                } catch (PackageManager.NameNotFoundException e) {
3116                    Slog.w(TAG, "Unable to retrieve gids", e);
3117                }
3118
3119                /*
3120                 * Add shared application and profile GIDs so applications can share some
3121                 * resources like shared libraries and access user-wide resources
3122                 */
3123                if (permGids == null) {
3124                    gids = new int[2];
3125                } else {
3126                    gids = new int[permGids.length + 2];
3127                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3128                }
3129                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3130                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3131            }
3132            checkTime(startTime, "startProcess: building args");
3133            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3134                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3135                        && mTopComponent != null
3136                        && app.processName.equals(mTopComponent.getPackageName())) {
3137                    uid = 0;
3138                }
3139                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3140                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3141                    uid = 0;
3142                }
3143            }
3144            int debugFlags = 0;
3145            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3146                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3147                // Also turn on CheckJNI for debuggable apps. It's quite
3148                // awkward to turn on otherwise.
3149                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3150            }
3151            // Run the app in safe mode if its manifest requests so or the
3152            // system is booted in safe mode.
3153            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3154                mSafeMode == true) {
3155                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3156            }
3157            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3158                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3159            }
3160            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3161                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3162            }
3163            if ("1".equals(SystemProperties.get("debug.assert"))) {
3164                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3165            }
3166
3167            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3168            if (requiredAbi == null) {
3169                requiredAbi = Build.SUPPORTED_ABIS[0];
3170            }
3171
3172            String instructionSet = null;
3173            if (app.info.primaryCpuAbi != null) {
3174                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3175            }
3176
3177            // Start the process.  It will either succeed and return a result containing
3178            // the PID of the new process, or else throw a RuntimeException.
3179            boolean isActivityProcess = (entryPoint == null);
3180            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3181            checkTime(startTime, "startProcess: asking zygote to start proc");
3182            Process.ProcessStartResult startResult = Process.start(entryPoint,
3183                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3184                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3185                    app.info.dataDir, entryPointArgs);
3186            checkTime(startTime, "startProcess: returned from zygote!");
3187
3188            if (app.isolated) {
3189                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3190            }
3191            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3192            checkTime(startTime, "startProcess: done updating battery stats");
3193
3194            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3195                    UserHandle.getUserId(uid), startResult.pid, uid,
3196                    app.processName, hostingType,
3197                    hostingNameStr != null ? hostingNameStr : "");
3198
3199            if (app.persistent) {
3200                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3201            }
3202
3203            checkTime(startTime, "startProcess: building log message");
3204            StringBuilder buf = mStringBuilder;
3205            buf.setLength(0);
3206            buf.append("Start proc ");
3207            buf.append(app.processName);
3208            if (!isActivityProcess) {
3209                buf.append(" [");
3210                buf.append(entryPoint);
3211                buf.append("]");
3212            }
3213            buf.append(" for ");
3214            buf.append(hostingType);
3215            if (hostingNameStr != null) {
3216                buf.append(" ");
3217                buf.append(hostingNameStr);
3218            }
3219            buf.append(": pid=");
3220            buf.append(startResult.pid);
3221            buf.append(" uid=");
3222            buf.append(uid);
3223            buf.append(" gids={");
3224            if (gids != null) {
3225                for (int gi=0; gi<gids.length; gi++) {
3226                    if (gi != 0) buf.append(", ");
3227                    buf.append(gids[gi]);
3228
3229                }
3230            }
3231            buf.append("}");
3232            if (requiredAbi != null) {
3233                buf.append(" abi=");
3234                buf.append(requiredAbi);
3235            }
3236            Slog.i(TAG, buf.toString());
3237            app.setPid(startResult.pid);
3238            app.usingWrapper = startResult.usingWrapper;
3239            app.removed = false;
3240            app.killed = false;
3241            app.killedByAm = false;
3242            checkTime(startTime, "startProcess: starting to update pids map");
3243            synchronized (mPidsSelfLocked) {
3244                this.mPidsSelfLocked.put(startResult.pid, app);
3245                if (isActivityProcess) {
3246                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3247                    msg.obj = app;
3248                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3249                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3250                }
3251            }
3252            checkTime(startTime, "startProcess: done updating pids map");
3253        } catch (RuntimeException e) {
3254            // XXX do better error recovery.
3255            app.setPid(0);
3256            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3257            if (app.isolated) {
3258                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3259            }
3260            Slog.e(TAG, "Failure starting process " + app.processName, e);
3261        }
3262    }
3263
3264    void updateUsageStats(ActivityRecord component, boolean resumed) {
3265        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3266        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3267        if (resumed) {
3268            if (mUsageStatsService != null) {
3269                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3270                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3271            }
3272            synchronized (stats) {
3273                stats.noteActivityResumedLocked(component.app.uid);
3274            }
3275        } else {
3276            if (mUsageStatsService != null) {
3277                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3278                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3279            }
3280            synchronized (stats) {
3281                stats.noteActivityPausedLocked(component.app.uid);
3282            }
3283        }
3284    }
3285
3286    Intent getHomeIntent() {
3287        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3288        intent.setComponent(mTopComponent);
3289        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3290            intent.addCategory(Intent.CATEGORY_HOME);
3291        }
3292        return intent;
3293    }
3294
3295    boolean startHomeActivityLocked(int userId) {
3296        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3297                && mTopAction == null) {
3298            // We are running in factory test mode, but unable to find
3299            // the factory test app, so just sit around displaying the
3300            // error message and don't try to start anything.
3301            return false;
3302        }
3303        Intent intent = getHomeIntent();
3304        ActivityInfo aInfo =
3305            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3306        if (aInfo != null) {
3307            intent.setComponent(new ComponentName(
3308                    aInfo.applicationInfo.packageName, aInfo.name));
3309            // Don't do this if the home app is currently being
3310            // instrumented.
3311            aInfo = new ActivityInfo(aInfo);
3312            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3313            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3314                    aInfo.applicationInfo.uid, true);
3315            if (app == null || app.instrumentationClass == null) {
3316                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3317                mStackSupervisor.startHomeActivity(intent, aInfo);
3318            }
3319        }
3320
3321        return true;
3322    }
3323
3324    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3325        ActivityInfo ai = null;
3326        ComponentName comp = intent.getComponent();
3327        try {
3328            if (comp != null) {
3329                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3330            } else {
3331                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3332                        intent,
3333                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3334                            flags, userId);
3335
3336                if (info != null) {
3337                    ai = info.activityInfo;
3338                }
3339            }
3340        } catch (RemoteException e) {
3341            // ignore
3342        }
3343
3344        return ai;
3345    }
3346
3347    /**
3348     * Starts the "new version setup screen" if appropriate.
3349     */
3350    void startSetupActivityLocked() {
3351        // Only do this once per boot.
3352        if (mCheckedForSetup) {
3353            return;
3354        }
3355
3356        // We will show this screen if the current one is a different
3357        // version than the last one shown, and we are not running in
3358        // low-level factory test mode.
3359        final ContentResolver resolver = mContext.getContentResolver();
3360        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3361                Settings.Global.getInt(resolver,
3362                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3363            mCheckedForSetup = true;
3364
3365            // See if we should be showing the platform update setup UI.
3366            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3367            List<ResolveInfo> ris = mContext.getPackageManager()
3368                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3369
3370            // We don't allow third party apps to replace this.
3371            ResolveInfo ri = null;
3372            for (int i=0; ris != null && i<ris.size(); i++) {
3373                if ((ris.get(i).activityInfo.applicationInfo.flags
3374                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3375                    ri = ris.get(i);
3376                    break;
3377                }
3378            }
3379
3380            if (ri != null) {
3381                String vers = ri.activityInfo.metaData != null
3382                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3383                        : null;
3384                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3385                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3386                            Intent.METADATA_SETUP_VERSION);
3387                }
3388                String lastVers = Settings.Secure.getString(
3389                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3390                if (vers != null && !vers.equals(lastVers)) {
3391                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3392                    intent.setComponent(new ComponentName(
3393                            ri.activityInfo.packageName, ri.activityInfo.name));
3394                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3395                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3396                            null);
3397                }
3398            }
3399        }
3400    }
3401
3402    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3403        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3404    }
3405
3406    void enforceNotIsolatedCaller(String caller) {
3407        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3408            throw new SecurityException("Isolated process not allowed to call " + caller);
3409        }
3410    }
3411
3412    void enforceShellRestriction(String restriction, int userHandle) {
3413        if (Binder.getCallingUid() == Process.SHELL_UID) {
3414            if (userHandle < 0
3415                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3416                throw new SecurityException("Shell does not have permission to access user "
3417                        + userHandle);
3418            }
3419        }
3420    }
3421
3422    @Override
3423    public int getFrontActivityScreenCompatMode() {
3424        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3425        synchronized (this) {
3426            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3427        }
3428    }
3429
3430    @Override
3431    public void setFrontActivityScreenCompatMode(int mode) {
3432        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3433                "setFrontActivityScreenCompatMode");
3434        synchronized (this) {
3435            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3436        }
3437    }
3438
3439    @Override
3440    public int getPackageScreenCompatMode(String packageName) {
3441        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3442        synchronized (this) {
3443            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3444        }
3445    }
3446
3447    @Override
3448    public void setPackageScreenCompatMode(String packageName, int mode) {
3449        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3450                "setPackageScreenCompatMode");
3451        synchronized (this) {
3452            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3453        }
3454    }
3455
3456    @Override
3457    public boolean getPackageAskScreenCompat(String packageName) {
3458        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3459        synchronized (this) {
3460            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3461        }
3462    }
3463
3464    @Override
3465    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3466        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3467                "setPackageAskScreenCompat");
3468        synchronized (this) {
3469            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3470        }
3471    }
3472
3473    private void dispatchProcessesChanged() {
3474        int N;
3475        synchronized (this) {
3476            N = mPendingProcessChanges.size();
3477            if (mActiveProcessChanges.length < N) {
3478                mActiveProcessChanges = new ProcessChangeItem[N];
3479            }
3480            mPendingProcessChanges.toArray(mActiveProcessChanges);
3481            mAvailProcessChanges.addAll(mPendingProcessChanges);
3482            mPendingProcessChanges.clear();
3483            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3484        }
3485
3486        int i = mProcessObservers.beginBroadcast();
3487        while (i > 0) {
3488            i--;
3489            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3490            if (observer != null) {
3491                try {
3492                    for (int j=0; j<N; j++) {
3493                        ProcessChangeItem item = mActiveProcessChanges[j];
3494                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3495                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3496                                    + item.pid + " uid=" + item.uid + ": "
3497                                    + item.foregroundActivities);
3498                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3499                                    item.foregroundActivities);
3500                        }
3501                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3502                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3503                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3504                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3505                        }
3506                    }
3507                } catch (RemoteException e) {
3508                }
3509            }
3510        }
3511        mProcessObservers.finishBroadcast();
3512    }
3513
3514    private void dispatchProcessDied(int pid, int uid) {
3515        int i = mProcessObservers.beginBroadcast();
3516        while (i > 0) {
3517            i--;
3518            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3519            if (observer != null) {
3520                try {
3521                    observer.onProcessDied(pid, uid);
3522                } catch (RemoteException e) {
3523                }
3524            }
3525        }
3526        mProcessObservers.finishBroadcast();
3527    }
3528
3529    @Override
3530    public final int startActivity(IApplicationThread caller, String callingPackage,
3531            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3532            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3533        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3534            resultWho, requestCode, startFlags, profilerInfo, options,
3535            UserHandle.getCallingUserId());
3536    }
3537
3538    @Override
3539    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3540            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3541            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3542        enforceNotIsolatedCaller("startActivity");
3543        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3544                false, ALLOW_FULL_ONLY, "startActivity", null);
3545        // TODO: Switch to user app stacks here.
3546        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3547                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3548                profilerInfo, null, null, options, userId, null, null);
3549    }
3550
3551    @Override
3552    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3553            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3554            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3555
3556        // This is very dangerous -- it allows you to perform a start activity (including
3557        // permission grants) as any app that may launch one of your own activities.  So
3558        // we will only allow this to be done from activities that are part of the core framework,
3559        // and then only when they are running as the system.
3560        final ActivityRecord sourceRecord;
3561        final int targetUid;
3562        final String targetPackage;
3563        synchronized (this) {
3564            if (resultTo == null) {
3565                throw new SecurityException("Must be called from an activity");
3566            }
3567            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3568            if (sourceRecord == null) {
3569                throw new SecurityException("Called with bad activity token: " + resultTo);
3570            }
3571            if (!sourceRecord.info.packageName.equals("android")) {
3572                throw new SecurityException(
3573                        "Must be called from an activity that is declared in the android package");
3574            }
3575            if (sourceRecord.app == null) {
3576                throw new SecurityException("Called without a process attached to activity");
3577            }
3578            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3579                // This is still okay, as long as this activity is running under the
3580                // uid of the original calling activity.
3581                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3582                    throw new SecurityException(
3583                            "Calling activity in uid " + sourceRecord.app.uid
3584                                    + " must be system uid or original calling uid "
3585                                    + sourceRecord.launchedFromUid);
3586                }
3587            }
3588            targetUid = sourceRecord.launchedFromUid;
3589            targetPackage = sourceRecord.launchedFromPackage;
3590        }
3591
3592        // TODO: Switch to user app stacks here.
3593        try {
3594            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3595                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3596                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3597            return ret;
3598        } catch (SecurityException e) {
3599            // XXX need to figure out how to propagate to original app.
3600            // A SecurityException here is generally actually a fault of the original
3601            // calling activity (such as a fairly granting permissions), so propagate it
3602            // back to them.
3603            /*
3604            StringBuilder msg = new StringBuilder();
3605            msg.append("While launching");
3606            msg.append(intent.toString());
3607            msg.append(": ");
3608            msg.append(e.getMessage());
3609            */
3610            throw e;
3611        }
3612    }
3613
3614    @Override
3615    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3616            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3617            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3618        enforceNotIsolatedCaller("startActivityAndWait");
3619        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3620                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3621        WaitResult res = new WaitResult();
3622        // TODO: Switch to user app stacks here.
3623        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3624                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3625                options, userId, null, null);
3626        return res;
3627    }
3628
3629    @Override
3630    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3631            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3632            int startFlags, Configuration config, Bundle options, int userId) {
3633        enforceNotIsolatedCaller("startActivityWithConfig");
3634        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3635                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3636        // TODO: Switch to user app stacks here.
3637        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3638                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3639                null, null, config, options, userId, null, null);
3640        return ret;
3641    }
3642
3643    @Override
3644    public int startActivityIntentSender(IApplicationThread caller,
3645            IntentSender intent, Intent fillInIntent, String resolvedType,
3646            IBinder resultTo, String resultWho, int requestCode,
3647            int flagsMask, int flagsValues, Bundle options) {
3648        enforceNotIsolatedCaller("startActivityIntentSender");
3649        // Refuse possible leaked file descriptors
3650        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3651            throw new IllegalArgumentException("File descriptors passed in Intent");
3652        }
3653
3654        IIntentSender sender = intent.getTarget();
3655        if (!(sender instanceof PendingIntentRecord)) {
3656            throw new IllegalArgumentException("Bad PendingIntent object");
3657        }
3658
3659        PendingIntentRecord pir = (PendingIntentRecord)sender;
3660
3661        synchronized (this) {
3662            // If this is coming from the currently resumed activity, it is
3663            // effectively saying that app switches are allowed at this point.
3664            final ActivityStack stack = getFocusedStack();
3665            if (stack.mResumedActivity != null &&
3666                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3667                mAppSwitchesAllowedTime = 0;
3668            }
3669        }
3670        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3671                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3672        return ret;
3673    }
3674
3675    @Override
3676    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3677            Intent intent, String resolvedType, IVoiceInteractionSession session,
3678            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3679            Bundle options, int userId) {
3680        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3681                != PackageManager.PERMISSION_GRANTED) {
3682            String msg = "Permission Denial: startVoiceActivity() from pid="
3683                    + Binder.getCallingPid()
3684                    + ", uid=" + Binder.getCallingUid()
3685                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3686            Slog.w(TAG, msg);
3687            throw new SecurityException(msg);
3688        }
3689        if (session == null || interactor == null) {
3690            throw new NullPointerException("null session or interactor");
3691        }
3692        userId = handleIncomingUser(callingPid, callingUid, userId,
3693                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3694        // TODO: Switch to user app stacks here.
3695        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3696                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3697                null, options, userId, null, null);
3698    }
3699
3700    @Override
3701    public boolean startNextMatchingActivity(IBinder callingActivity,
3702            Intent intent, Bundle options) {
3703        // Refuse possible leaked file descriptors
3704        if (intent != null && intent.hasFileDescriptors() == true) {
3705            throw new IllegalArgumentException("File descriptors passed in Intent");
3706        }
3707
3708        synchronized (this) {
3709            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3710            if (r == null) {
3711                ActivityOptions.abort(options);
3712                return false;
3713            }
3714            if (r.app == null || r.app.thread == null) {
3715                // The caller is not running...  d'oh!
3716                ActivityOptions.abort(options);
3717                return false;
3718            }
3719            intent = new Intent(intent);
3720            // The caller is not allowed to change the data.
3721            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3722            // And we are resetting to find the next component...
3723            intent.setComponent(null);
3724
3725            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3726
3727            ActivityInfo aInfo = null;
3728            try {
3729                List<ResolveInfo> resolves =
3730                    AppGlobals.getPackageManager().queryIntentActivities(
3731                            intent, r.resolvedType,
3732                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3733                            UserHandle.getCallingUserId());
3734
3735                // Look for the original activity in the list...
3736                final int N = resolves != null ? resolves.size() : 0;
3737                for (int i=0; i<N; i++) {
3738                    ResolveInfo rInfo = resolves.get(i);
3739                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3740                            && rInfo.activityInfo.name.equals(r.info.name)) {
3741                        // We found the current one...  the next matching is
3742                        // after it.
3743                        i++;
3744                        if (i<N) {
3745                            aInfo = resolves.get(i).activityInfo;
3746                        }
3747                        if (debug) {
3748                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3749                                    + "/" + r.info.name);
3750                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3751                                    + "/" + aInfo.name);
3752                        }
3753                        break;
3754                    }
3755                }
3756            } catch (RemoteException e) {
3757            }
3758
3759            if (aInfo == null) {
3760                // Nobody who is next!
3761                ActivityOptions.abort(options);
3762                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3763                return false;
3764            }
3765
3766            intent.setComponent(new ComponentName(
3767                    aInfo.applicationInfo.packageName, aInfo.name));
3768            intent.setFlags(intent.getFlags()&~(
3769                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3770                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3771                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3772                    Intent.FLAG_ACTIVITY_NEW_TASK));
3773
3774            // Okay now we need to start the new activity, replacing the
3775            // currently running activity.  This is a little tricky because
3776            // we want to start the new one as if the current one is finished,
3777            // but not finish the current one first so that there is no flicker.
3778            // And thus...
3779            final boolean wasFinishing = r.finishing;
3780            r.finishing = true;
3781
3782            // Propagate reply information over to the new activity.
3783            final ActivityRecord resultTo = r.resultTo;
3784            final String resultWho = r.resultWho;
3785            final int requestCode = r.requestCode;
3786            r.resultTo = null;
3787            if (resultTo != null) {
3788                resultTo.removeResultsLocked(r, resultWho, requestCode);
3789            }
3790
3791            final long origId = Binder.clearCallingIdentity();
3792            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3793                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3794                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3795                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3796            Binder.restoreCallingIdentity(origId);
3797
3798            r.finishing = wasFinishing;
3799            if (res != ActivityManager.START_SUCCESS) {
3800                return false;
3801            }
3802            return true;
3803        }
3804    }
3805
3806    @Override
3807    public final int startActivityFromRecents(int taskId, Bundle options) {
3808        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3809            String msg = "Permission Denial: startActivityFromRecents called without " +
3810                    START_TASKS_FROM_RECENTS;
3811            Slog.w(TAG, msg);
3812            throw new SecurityException(msg);
3813        }
3814        return startActivityFromRecentsInner(taskId, options);
3815    }
3816
3817    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3818        final TaskRecord task;
3819        final int callingUid;
3820        final String callingPackage;
3821        final Intent intent;
3822        final int userId;
3823        synchronized (this) {
3824            task = recentTaskForIdLocked(taskId);
3825            if (task == null) {
3826                throw new IllegalArgumentException("Task " + taskId + " not found.");
3827            }
3828            callingUid = task.mCallingUid;
3829            callingPackage = task.mCallingPackage;
3830            intent = task.intent;
3831            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3832            userId = task.userId;
3833        }
3834        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3835                options, userId, null, task);
3836    }
3837
3838    final int startActivityInPackage(int uid, String callingPackage,
3839            Intent intent, String resolvedType, IBinder resultTo,
3840            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3841            IActivityContainer container, TaskRecord inTask) {
3842
3843        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3844                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3845
3846        // TODO: Switch to user app stacks here.
3847        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3848                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3849                null, null, null, options, userId, container, inTask);
3850        return ret;
3851    }
3852
3853    @Override
3854    public final int startActivities(IApplicationThread caller, String callingPackage,
3855            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3856            int userId) {
3857        enforceNotIsolatedCaller("startActivities");
3858        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3859                false, ALLOW_FULL_ONLY, "startActivity", null);
3860        // TODO: Switch to user app stacks here.
3861        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3862                resolvedTypes, resultTo, options, userId);
3863        return ret;
3864    }
3865
3866    final int startActivitiesInPackage(int uid, String callingPackage,
3867            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3868            Bundle options, int userId) {
3869
3870        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3871                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3872        // TODO: Switch to user app stacks here.
3873        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3874                resultTo, options, userId);
3875        return ret;
3876    }
3877
3878    //explicitly remove thd old information in mRecentTasks when removing existing user.
3879    private void removeRecentTasksForUserLocked(int userId) {
3880        if(userId <= 0) {
3881            Slog.i(TAG, "Can't remove recent task on user " + userId);
3882            return;
3883        }
3884
3885        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3886            TaskRecord tr = mRecentTasks.get(i);
3887            if (tr.userId == userId) {
3888                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3889                        + " when finishing user" + userId);
3890                mRecentTasks.remove(i);
3891                tr.removedFromRecents(mTaskPersister);
3892            }
3893        }
3894
3895        // Remove tasks from persistent storage.
3896        mTaskPersister.wakeup(null, true);
3897    }
3898
3899    // Sort by taskId
3900    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3901        @Override
3902        public int compare(TaskRecord lhs, TaskRecord rhs) {
3903            return rhs.taskId - lhs.taskId;
3904        }
3905    };
3906
3907    // Extract the affiliates of the chain containing mRecentTasks[start].
3908    private int processNextAffiliateChain(int start) {
3909        final TaskRecord startTask = mRecentTasks.get(start);
3910        final int affiliateId = startTask.mAffiliatedTaskId;
3911
3912        // Quick identification of isolated tasks. I.e. those not launched behind.
3913        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3914                startTask.mNextAffiliate == null) {
3915            // There is still a slim chance that there are other tasks that point to this task
3916            // and that the chain is so messed up that this task no longer points to them but
3917            // the gain of this optimization outweighs the risk.
3918            startTask.inRecents = true;
3919            return start + 1;
3920        }
3921
3922        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3923        mTmpRecents.clear();
3924        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3925            final TaskRecord task = mRecentTasks.get(i);
3926            if (task.mAffiliatedTaskId == affiliateId) {
3927                mRecentTasks.remove(i);
3928                mTmpRecents.add(task);
3929            }
3930        }
3931
3932        // Sort them all by taskId. That is the order they were create in and that order will
3933        // always be correct.
3934        Collections.sort(mTmpRecents, mTaskRecordComparator);
3935
3936        // Go through and fix up the linked list.
3937        // The first one is the end of the chain and has no next.
3938        final TaskRecord first = mTmpRecents.get(0);
3939        first.inRecents = true;
3940        if (first.mNextAffiliate != null) {
3941            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3942            first.setNextAffiliate(null);
3943            mTaskPersister.wakeup(first, false);
3944        }
3945        // Everything in the middle is doubly linked from next to prev.
3946        final int tmpSize = mTmpRecents.size();
3947        for (int i = 0; i < tmpSize - 1; ++i) {
3948            final TaskRecord next = mTmpRecents.get(i);
3949            final TaskRecord prev = mTmpRecents.get(i + 1);
3950            if (next.mPrevAffiliate != prev) {
3951                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3952                        " setting prev=" + prev);
3953                next.setPrevAffiliate(prev);
3954                mTaskPersister.wakeup(next, false);
3955            }
3956            if (prev.mNextAffiliate != next) {
3957                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3958                        " setting next=" + next);
3959                prev.setNextAffiliate(next);
3960                mTaskPersister.wakeup(prev, false);
3961            }
3962            prev.inRecents = true;
3963        }
3964        // The last one is the beginning of the list and has no prev.
3965        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3966        if (last.mPrevAffiliate != null) {
3967            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3968            last.setPrevAffiliate(null);
3969            mTaskPersister.wakeup(last, false);
3970        }
3971
3972        // Insert the group back into mRecentTasks at start.
3973        mRecentTasks.addAll(start, mTmpRecents);
3974
3975        // Let the caller know where we left off.
3976        return start + tmpSize;
3977    }
3978
3979    /**
3980     * Update the recent tasks lists: make sure tasks should still be here (their
3981     * applications / activities still exist), update their availability, fixup ordering
3982     * of affiliations.
3983     */
3984    void cleanupRecentTasksLocked(int userId) {
3985        if (mRecentTasks == null) {
3986            // Happens when called from the packagemanager broadcast before boot.
3987            return;
3988        }
3989
3990        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3991        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3992        final IPackageManager pm = AppGlobals.getPackageManager();
3993        final ActivityInfo dummyAct = new ActivityInfo();
3994        final ApplicationInfo dummyApp = new ApplicationInfo();
3995
3996        int N = mRecentTasks.size();
3997
3998        int[] users = userId == UserHandle.USER_ALL
3999                ? getUsersLocked() : new int[] { userId };
4000        for (int user : users) {
4001            for (int i = 0; i < N; i++) {
4002                TaskRecord task = mRecentTasks.get(i);
4003                if (task.userId != user) {
4004                    // Only look at tasks for the user ID of interest.
4005                    continue;
4006                }
4007                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4008                    // This situation is broken, and we should just get rid of it now.
4009                    mRecentTasks.remove(i);
4010                    task.removedFromRecents(mTaskPersister);
4011                    i--;
4012                    N--;
4013                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4014                    continue;
4015                }
4016                // Check whether this activity is currently available.
4017                if (task.realActivity != null) {
4018                    ActivityInfo ai = availActCache.get(task.realActivity);
4019                    if (ai == null) {
4020                        try {
4021                            ai = pm.getActivityInfo(task.realActivity,
4022                                    PackageManager.GET_UNINSTALLED_PACKAGES
4023                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4024                        } catch (RemoteException e) {
4025                            // Will never happen.
4026                            continue;
4027                        }
4028                        if (ai == null) {
4029                            ai = dummyAct;
4030                        }
4031                        availActCache.put(task.realActivity, ai);
4032                    }
4033                    if (ai == dummyAct) {
4034                        // This could be either because the activity no longer exists, or the
4035                        // app is temporarily gone.  For the former we want to remove the recents
4036                        // entry; for the latter we want to mark it as unavailable.
4037                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4038                        if (app == null) {
4039                            try {
4040                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4041                                        PackageManager.GET_UNINSTALLED_PACKAGES
4042                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4043                            } catch (RemoteException e) {
4044                                // Will never happen.
4045                                continue;
4046                            }
4047                            if (app == null) {
4048                                app = dummyApp;
4049                            }
4050                            availAppCache.put(task.realActivity.getPackageName(), app);
4051                        }
4052                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4053                            // Doesn't exist any more!  Good-bye.
4054                            mRecentTasks.remove(i);
4055                            task.removedFromRecents(mTaskPersister);
4056                            i--;
4057                            N--;
4058                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4059                            continue;
4060                        } else {
4061                            // Otherwise just not available for now.
4062                            if (task.isAvailable) {
4063                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4064                                        + task);
4065                            }
4066                            task.isAvailable = false;
4067                        }
4068                    } else {
4069                        if (!ai.enabled || !ai.applicationInfo.enabled
4070                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4071                            if (task.isAvailable) {
4072                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4073                                        + task + " (enabled=" + ai.enabled + "/"
4074                                        + ai.applicationInfo.enabled +  " flags="
4075                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4076                            }
4077                            task.isAvailable = false;
4078                        } else {
4079                            if (!task.isAvailable) {
4080                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4081                                        + task);
4082                            }
4083                            task.isAvailable = true;
4084                        }
4085                    }
4086                }
4087            }
4088        }
4089
4090        // Verify the affiliate chain for each task.
4091        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4092        }
4093
4094        mTmpRecents.clear();
4095        // mRecentTasks is now in sorted, affiliated order.
4096    }
4097
4098    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4099        int N = mRecentTasks.size();
4100        TaskRecord top = task;
4101        int topIndex = taskIndex;
4102        while (top.mNextAffiliate != null && topIndex > 0) {
4103            top = top.mNextAffiliate;
4104            topIndex--;
4105        }
4106        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4107                + topIndex + " from intial " + taskIndex);
4108        // Find the end of the chain, doing a sanity check along the way.
4109        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4110        int endIndex = topIndex;
4111        TaskRecord prev = top;
4112        while (endIndex < N) {
4113            TaskRecord cur = mRecentTasks.get(endIndex);
4114            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4115                    + endIndex + " " + cur);
4116            if (cur == top) {
4117                // Verify start of the chain.
4118                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4119                    Slog.wtf(TAG, "Bad chain @" + endIndex
4120                            + ": first task has next affiliate: " + prev);
4121                    sane = false;
4122                    break;
4123                }
4124            } else {
4125                // Verify middle of the chain's next points back to the one before.
4126                if (cur.mNextAffiliate != prev
4127                        || cur.mNextAffiliateTaskId != prev.taskId) {
4128                    Slog.wtf(TAG, "Bad chain @" + endIndex
4129                            + ": middle task " + cur + " @" + endIndex
4130                            + " has bad next affiliate "
4131                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4132                            + ", expected " + prev);
4133                    sane = false;
4134                    break;
4135                }
4136            }
4137            if (cur.mPrevAffiliateTaskId == -1) {
4138                // Chain ends here.
4139                if (cur.mPrevAffiliate != null) {
4140                    Slog.wtf(TAG, "Bad chain @" + endIndex
4141                            + ": last task " + cur + " has previous affiliate "
4142                            + cur.mPrevAffiliate);
4143                    sane = false;
4144                }
4145                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4146                break;
4147            } else {
4148                // Verify middle of the chain's prev points to a valid item.
4149                if (cur.mPrevAffiliate == null) {
4150                    Slog.wtf(TAG, "Bad chain @" + endIndex
4151                            + ": task " + cur + " has previous affiliate "
4152                            + cur.mPrevAffiliate + " but should be id "
4153                            + cur.mPrevAffiliate);
4154                    sane = false;
4155                    break;
4156                }
4157            }
4158            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4159                Slog.wtf(TAG, "Bad chain @" + endIndex
4160                        + ": task " + cur + " has affiliated id "
4161                        + cur.mAffiliatedTaskId + " but should be "
4162                        + task.mAffiliatedTaskId);
4163                sane = false;
4164                break;
4165            }
4166            prev = cur;
4167            endIndex++;
4168            if (endIndex >= N) {
4169                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4170                        + ": last task " + prev);
4171                sane = false;
4172                break;
4173            }
4174        }
4175        if (sane) {
4176            if (endIndex < taskIndex) {
4177                Slog.wtf(TAG, "Bad chain @" + endIndex
4178                        + ": did not extend to task " + task + " @" + taskIndex);
4179                sane = false;
4180            }
4181        }
4182        if (sane) {
4183            // All looks good, we can just move all of the affiliated tasks
4184            // to the top.
4185            for (int i=topIndex; i<=endIndex; i++) {
4186                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4187                        + " from " + i + " to " + (i-topIndex));
4188                TaskRecord cur = mRecentTasks.remove(i);
4189                mRecentTasks.add(i-topIndex, cur);
4190            }
4191            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4192                    + " to " + endIndex);
4193            return true;
4194        }
4195
4196        // Whoops, couldn't do it.
4197        return false;
4198    }
4199
4200    final void addRecentTaskLocked(TaskRecord task) {
4201        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4202                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4203
4204        int N = mRecentTasks.size();
4205        // Quick case: check if the top-most recent task is the same.
4206        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4207            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4208            return;
4209        }
4210        // Another quick case: check if this is part of a set of affiliated
4211        // tasks that are at the top.
4212        if (isAffiliated && N > 0 && task.inRecents
4213                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4214            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4215                    + " at top when adding " + task);
4216            return;
4217        }
4218        // Another quick case: never add voice sessions.
4219        if (task.voiceSession != null) {
4220            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4221            return;
4222        }
4223
4224        boolean needAffiliationFix = false;
4225
4226        // Slightly less quick case: the task is already in recents, so all we need
4227        // to do is move it.
4228        if (task.inRecents) {
4229            int taskIndex = mRecentTasks.indexOf(task);
4230            if (taskIndex >= 0) {
4231                if (!isAffiliated) {
4232                    // Simple case: this is not an affiliated task, so we just move it to the front.
4233                    mRecentTasks.remove(taskIndex);
4234                    mRecentTasks.add(0, task);
4235                    notifyTaskPersisterLocked(task, false);
4236                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4237                            + " from " + taskIndex);
4238                    return;
4239                } else {
4240                    // More complicated: need to keep all affiliated tasks together.
4241                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4242                        // All went well.
4243                        return;
4244                    }
4245
4246                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4247                    // everything and then go through our general path of adding a new task.
4248                    needAffiliationFix = true;
4249                }
4250            } else {
4251                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4252                needAffiliationFix = true;
4253            }
4254        }
4255
4256        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4257        trimRecentsForTask(task, true);
4258
4259        N = mRecentTasks.size();
4260        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4261            final TaskRecord tr = mRecentTasks.remove(N - 1);
4262            tr.removedFromRecents(mTaskPersister);
4263            N--;
4264        }
4265        task.inRecents = true;
4266        if (!isAffiliated || needAffiliationFix) {
4267            // If this is a simple non-affiliated task, or we had some failure trying to
4268            // handle it as part of an affilated task, then just place it at the top.
4269            mRecentTasks.add(0, task);
4270        } else if (isAffiliated) {
4271            // If this is a new affiliated task, then move all of the affiliated tasks
4272            // to the front and insert this new one.
4273            TaskRecord other = task.mNextAffiliate;
4274            if (other == null) {
4275                other = task.mPrevAffiliate;
4276            }
4277            if (other != null) {
4278                int otherIndex = mRecentTasks.indexOf(other);
4279                if (otherIndex >= 0) {
4280                    // Insert new task at appropriate location.
4281                    int taskIndex;
4282                    if (other == task.mNextAffiliate) {
4283                        // We found the index of our next affiliation, which is who is
4284                        // before us in the list, so add after that point.
4285                        taskIndex = otherIndex+1;
4286                    } else {
4287                        // We found the index of our previous affiliation, which is who is
4288                        // after us in the list, so add at their position.
4289                        taskIndex = otherIndex;
4290                    }
4291                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4292                            + taskIndex + ": " + task);
4293                    mRecentTasks.add(taskIndex, task);
4294
4295                    // Now move everything to the front.
4296                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4297                        // All went well.
4298                        return;
4299                    }
4300
4301                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4302                    // everything and then go through our general path of adding a new task.
4303                    needAffiliationFix = true;
4304                } else {
4305                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4306                            + other);
4307                    needAffiliationFix = true;
4308                }
4309            } else {
4310                if (DEBUG_RECENTS) Slog.d(TAG,
4311                        "addRecent: adding affiliated task without next/prev:" + task);
4312                needAffiliationFix = true;
4313            }
4314        }
4315        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4316
4317        if (needAffiliationFix) {
4318            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4319            cleanupRecentTasksLocked(task.userId);
4320        }
4321    }
4322
4323    /**
4324     * If needed, remove oldest existing entries in recents that are for the same kind
4325     * of task as the given one.
4326     */
4327    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4328        int N = mRecentTasks.size();
4329        final Intent intent = task.intent;
4330        final boolean document = intent != null && intent.isDocument();
4331
4332        int maxRecents = task.maxRecents - 1;
4333        for (int i=0; i<N; i++) {
4334            final TaskRecord tr = mRecentTasks.get(i);
4335            if (task != tr) {
4336                if (task.userId != tr.userId) {
4337                    continue;
4338                }
4339                if (i > MAX_RECENT_BITMAPS) {
4340                    tr.freeLastThumbnail();
4341                }
4342                final Intent trIntent = tr.intent;
4343                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4344                    (intent == null || !intent.filterEquals(trIntent))) {
4345                    continue;
4346                }
4347                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4348                if (document && trIsDocument) {
4349                    // These are the same document activity (not necessarily the same doc).
4350                    if (maxRecents > 0) {
4351                        --maxRecents;
4352                        continue;
4353                    }
4354                    // Hit the maximum number of documents for this task. Fall through
4355                    // and remove this document from recents.
4356                } else if (document || trIsDocument) {
4357                    // Only one of these is a document. Not the droid we're looking for.
4358                    continue;
4359                }
4360            }
4361
4362            if (!doTrim) {
4363                // If the caller is not actually asking for a trim, just tell them we reached
4364                // a point where the trim would happen.
4365                return i;
4366            }
4367
4368            // Either task and tr are the same or, their affinities match or their intents match
4369            // and neither of them is a document, or they are documents using the same activity
4370            // and their maxRecents has been reached.
4371            tr.disposeThumbnail();
4372            mRecentTasks.remove(i);
4373            if (task != tr) {
4374                tr.removedFromRecents(mTaskPersister);
4375            }
4376            i--;
4377            N--;
4378            if (task.intent == null) {
4379                // If the new recent task we are adding is not fully
4380                // specified, then replace it with the existing recent task.
4381                task = tr;
4382            }
4383            notifyTaskPersisterLocked(tr, false);
4384        }
4385
4386        return -1;
4387    }
4388
4389    @Override
4390    public void reportActivityFullyDrawn(IBinder token) {
4391        synchronized (this) {
4392            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4393            if (r == null) {
4394                return;
4395            }
4396            r.reportFullyDrawnLocked();
4397        }
4398    }
4399
4400    @Override
4401    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4402        synchronized (this) {
4403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404            if (r == null) {
4405                return;
4406            }
4407            final long origId = Binder.clearCallingIdentity();
4408            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4409            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4410                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4411            if (config != null) {
4412                r.frozenBeforeDestroy = true;
4413                if (!updateConfigurationLocked(config, r, false, false)) {
4414                    mStackSupervisor.resumeTopActivitiesLocked();
4415                }
4416            }
4417            Binder.restoreCallingIdentity(origId);
4418        }
4419    }
4420
4421    @Override
4422    public int getRequestedOrientation(IBinder token) {
4423        synchronized (this) {
4424            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4425            if (r == null) {
4426                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4427            }
4428            return mWindowManager.getAppOrientation(r.appToken);
4429        }
4430    }
4431
4432    /**
4433     * This is the internal entry point for handling Activity.finish().
4434     *
4435     * @param token The Binder token referencing the Activity we want to finish.
4436     * @param resultCode Result code, if any, from this Activity.
4437     * @param resultData Result data (Intent), if any, from this Activity.
4438     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4439     *            the root Activity in the task.
4440     *
4441     * @return Returns true if the activity successfully finished, or false if it is still running.
4442     */
4443    @Override
4444    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4445            boolean finishTask) {
4446        // Refuse possible leaked file descriptors
4447        if (resultData != null && resultData.hasFileDescriptors() == true) {
4448            throw new IllegalArgumentException("File descriptors passed in Intent");
4449        }
4450
4451        synchronized(this) {
4452            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4453            if (r == null) {
4454                return true;
4455            }
4456            // Keep track of the root activity of the task before we finish it
4457            TaskRecord tr = r.task;
4458            ActivityRecord rootR = tr.getRootActivity();
4459            // Do not allow task to finish in Lock Task mode.
4460            if (tr == mStackSupervisor.mLockTaskModeTask) {
4461                if (rootR == r) {
4462                    mStackSupervisor.showLockTaskToast();
4463                    return false;
4464                }
4465            }
4466            if (mController != null) {
4467                // Find the first activity that is not finishing.
4468                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4469                if (next != null) {
4470                    // ask watcher if this is allowed
4471                    boolean resumeOK = true;
4472                    try {
4473                        resumeOK = mController.activityResuming(next.packageName);
4474                    } catch (RemoteException e) {
4475                        mController = null;
4476                        Watchdog.getInstance().setActivityController(null);
4477                    }
4478
4479                    if (!resumeOK) {
4480                        return false;
4481                    }
4482                }
4483            }
4484            final long origId = Binder.clearCallingIdentity();
4485            try {
4486                boolean res;
4487                if (finishTask && r == rootR) {
4488                    // If requested, remove the task that is associated to this activity only if it
4489                    // was the root activity in the task.  The result code and data is ignored because
4490                    // we don't support returning them across task boundaries.
4491                    res = removeTaskByIdLocked(tr.taskId, 0);
4492                } else {
4493                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4494                            resultData, "app-request", true);
4495                }
4496                return res;
4497            } finally {
4498                Binder.restoreCallingIdentity(origId);
4499            }
4500        }
4501    }
4502
4503    @Override
4504    public final void finishHeavyWeightApp() {
4505        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4506                != PackageManager.PERMISSION_GRANTED) {
4507            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4508                    + Binder.getCallingPid()
4509                    + ", uid=" + Binder.getCallingUid()
4510                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4511            Slog.w(TAG, msg);
4512            throw new SecurityException(msg);
4513        }
4514
4515        synchronized(this) {
4516            if (mHeavyWeightProcess == null) {
4517                return;
4518            }
4519
4520            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4521                    mHeavyWeightProcess.activities);
4522            for (int i=0; i<activities.size(); i++) {
4523                ActivityRecord r = activities.get(i);
4524                if (!r.finishing) {
4525                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4526                            null, "finish-heavy", true);
4527                }
4528            }
4529
4530            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4531                    mHeavyWeightProcess.userId, 0));
4532            mHeavyWeightProcess = null;
4533        }
4534    }
4535
4536    @Override
4537    public void crashApplication(int uid, int initialPid, String packageName,
4538            String message) {
4539        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4540                != PackageManager.PERMISSION_GRANTED) {
4541            String msg = "Permission Denial: crashApplication() from pid="
4542                    + Binder.getCallingPid()
4543                    + ", uid=" + Binder.getCallingUid()
4544                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4545            Slog.w(TAG, msg);
4546            throw new SecurityException(msg);
4547        }
4548
4549        synchronized(this) {
4550            ProcessRecord proc = null;
4551
4552            // Figure out which process to kill.  We don't trust that initialPid
4553            // still has any relation to current pids, so must scan through the
4554            // list.
4555            synchronized (mPidsSelfLocked) {
4556                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4557                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4558                    if (p.uid != uid) {
4559                        continue;
4560                    }
4561                    if (p.pid == initialPid) {
4562                        proc = p;
4563                        break;
4564                    }
4565                    if (p.pkgList.containsKey(packageName)) {
4566                        proc = p;
4567                    }
4568                }
4569            }
4570
4571            if (proc == null) {
4572                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4573                        + " initialPid=" + initialPid
4574                        + " packageName=" + packageName);
4575                return;
4576            }
4577
4578            if (proc.thread != null) {
4579                if (proc.pid == Process.myPid()) {
4580                    Log.w(TAG, "crashApplication: trying to crash self!");
4581                    return;
4582                }
4583                long ident = Binder.clearCallingIdentity();
4584                try {
4585                    proc.thread.scheduleCrash(message);
4586                } catch (RemoteException e) {
4587                }
4588                Binder.restoreCallingIdentity(ident);
4589            }
4590        }
4591    }
4592
4593    @Override
4594    public final void finishSubActivity(IBinder token, String resultWho,
4595            int requestCode) {
4596        synchronized(this) {
4597            final long origId = Binder.clearCallingIdentity();
4598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4599            if (r != null) {
4600                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4601            }
4602            Binder.restoreCallingIdentity(origId);
4603        }
4604    }
4605
4606    @Override
4607    public boolean finishActivityAffinity(IBinder token) {
4608        synchronized(this) {
4609            final long origId = Binder.clearCallingIdentity();
4610            try {
4611                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4612
4613                ActivityRecord rootR = r.task.getRootActivity();
4614                // Do not allow task to finish in Lock Task mode.
4615                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4616                    if (rootR == r) {
4617                        mStackSupervisor.showLockTaskToast();
4618                        return false;
4619                    }
4620                }
4621                boolean res = false;
4622                if (r != null) {
4623                    res = r.task.stack.finishActivityAffinityLocked(r);
4624                }
4625                return res;
4626            } finally {
4627                Binder.restoreCallingIdentity(origId);
4628            }
4629        }
4630    }
4631
4632    @Override
4633    public void finishVoiceTask(IVoiceInteractionSession session) {
4634        synchronized(this) {
4635            final long origId = Binder.clearCallingIdentity();
4636            try {
4637                mStackSupervisor.finishVoiceTask(session);
4638            } finally {
4639                Binder.restoreCallingIdentity(origId);
4640            }
4641        }
4642
4643    }
4644
4645    @Override
4646    public boolean releaseActivityInstance(IBinder token) {
4647        synchronized(this) {
4648            final long origId = Binder.clearCallingIdentity();
4649            try {
4650                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4651                if (r.task == null || r.task.stack == null) {
4652                    return false;
4653                }
4654                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4655            } finally {
4656                Binder.restoreCallingIdentity(origId);
4657            }
4658        }
4659    }
4660
4661    @Override
4662    public void releaseSomeActivities(IApplicationThread appInt) {
4663        synchronized(this) {
4664            final long origId = Binder.clearCallingIdentity();
4665            try {
4666                ProcessRecord app = getRecordForAppLocked(appInt);
4667                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4668            } finally {
4669                Binder.restoreCallingIdentity(origId);
4670            }
4671        }
4672    }
4673
4674    @Override
4675    public boolean willActivityBeVisible(IBinder token) {
4676        synchronized(this) {
4677            ActivityStack stack = ActivityRecord.getStackLocked(token);
4678            if (stack != null) {
4679                return stack.willActivityBeVisibleLocked(token);
4680            }
4681            return false;
4682        }
4683    }
4684
4685    @Override
4686    public void overridePendingTransition(IBinder token, String packageName,
4687            int enterAnim, int exitAnim) {
4688        synchronized(this) {
4689            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4690            if (self == null) {
4691                return;
4692            }
4693
4694            final long origId = Binder.clearCallingIdentity();
4695
4696            if (self.state == ActivityState.RESUMED
4697                    || self.state == ActivityState.PAUSING) {
4698                mWindowManager.overridePendingAppTransition(packageName,
4699                        enterAnim, exitAnim, null);
4700            }
4701
4702            Binder.restoreCallingIdentity(origId);
4703        }
4704    }
4705
4706    /**
4707     * Main function for removing an existing process from the activity manager
4708     * as a result of that process going away.  Clears out all connections
4709     * to the process.
4710     */
4711    private final void handleAppDiedLocked(ProcessRecord app,
4712            boolean restarting, boolean allowRestart) {
4713        int pid = app.pid;
4714        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4715        if (!kept && !restarting) {
4716            removeLruProcessLocked(app);
4717            if (pid > 0) {
4718                ProcessList.remove(pid);
4719            }
4720        }
4721
4722        if (mProfileProc == app) {
4723            clearProfilerLocked();
4724        }
4725
4726        // Remove this application's activities from active lists.
4727        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4728
4729        app.activities.clear();
4730
4731        if (app.instrumentationClass != null) {
4732            Slog.w(TAG, "Crash of app " + app.processName
4733                  + " running instrumentation " + app.instrumentationClass);
4734            Bundle info = new Bundle();
4735            info.putString("shortMsg", "Process crashed.");
4736            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4737        }
4738
4739        if (!restarting) {
4740            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4741                // If there was nothing to resume, and we are not already
4742                // restarting this process, but there is a visible activity that
4743                // is hosted by the process...  then make sure all visible
4744                // activities are running, taking care of restarting this
4745                // process.
4746                if (hasVisibleActivities) {
4747                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4748                }
4749            }
4750        }
4751    }
4752
4753    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4754        IBinder threadBinder = thread.asBinder();
4755        // Find the application record.
4756        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4757            ProcessRecord rec = mLruProcesses.get(i);
4758            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4759                return i;
4760            }
4761        }
4762        return -1;
4763    }
4764
4765    final ProcessRecord getRecordForAppLocked(
4766            IApplicationThread thread) {
4767        if (thread == null) {
4768            return null;
4769        }
4770
4771        int appIndex = getLRURecordIndexForAppLocked(thread);
4772        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4773    }
4774
4775    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4776        // If there are no longer any background processes running,
4777        // and the app that died was not running instrumentation,
4778        // then tell everyone we are now low on memory.
4779        boolean haveBg = false;
4780        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4781            ProcessRecord rec = mLruProcesses.get(i);
4782            if (rec.thread != null
4783                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4784                haveBg = true;
4785                break;
4786            }
4787        }
4788
4789        if (!haveBg) {
4790            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4791            if (doReport) {
4792                long now = SystemClock.uptimeMillis();
4793                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4794                    doReport = false;
4795                } else {
4796                    mLastMemUsageReportTime = now;
4797                }
4798            }
4799            final ArrayList<ProcessMemInfo> memInfos
4800                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4801            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4802            long now = SystemClock.uptimeMillis();
4803            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4804                ProcessRecord rec = mLruProcesses.get(i);
4805                if (rec == dyingProc || rec.thread == null) {
4806                    continue;
4807                }
4808                if (doReport) {
4809                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4810                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4811                }
4812                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4813                    // The low memory report is overriding any current
4814                    // state for a GC request.  Make sure to do
4815                    // heavy/important/visible/foreground processes first.
4816                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4817                        rec.lastRequestedGc = 0;
4818                    } else {
4819                        rec.lastRequestedGc = rec.lastLowMemory;
4820                    }
4821                    rec.reportLowMemory = true;
4822                    rec.lastLowMemory = now;
4823                    mProcessesToGc.remove(rec);
4824                    addProcessToGcListLocked(rec);
4825                }
4826            }
4827            if (doReport) {
4828                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4829                mHandler.sendMessage(msg);
4830            }
4831            scheduleAppGcsLocked();
4832        }
4833    }
4834
4835    final void appDiedLocked(ProcessRecord app) {
4836       appDiedLocked(app, app.pid, app.thread);
4837    }
4838
4839    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4840        // First check if this ProcessRecord is actually active for the pid.
4841        synchronized (mPidsSelfLocked) {
4842            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4843            if (curProc != app) {
4844                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4845                return;
4846            }
4847        }
4848
4849        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4850        synchronized (stats) {
4851            stats.noteProcessDiedLocked(app.info.uid, pid);
4852        }
4853
4854        Process.killProcessQuiet(pid);
4855        Process.killProcessGroup(app.info.uid, pid);
4856        app.killed = true;
4857
4858        // Clean up already done if the process has been re-started.
4859        if (app.pid == pid && app.thread != null &&
4860                app.thread.asBinder() == thread.asBinder()) {
4861            boolean doLowMem = app.instrumentationClass == null;
4862            boolean doOomAdj = doLowMem;
4863            if (!app.killedByAm) {
4864                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4865                        + ") has died");
4866                mAllowLowerMemLevel = true;
4867            } else {
4868                // Note that we always want to do oom adj to update our state with the
4869                // new number of procs.
4870                mAllowLowerMemLevel = false;
4871                doLowMem = false;
4872            }
4873            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4874            if (DEBUG_CLEANUP) Slog.v(
4875                TAG, "Dying app: " + app + ", pid: " + pid
4876                + ", thread: " + thread.asBinder());
4877            handleAppDiedLocked(app, false, true);
4878
4879            if (doOomAdj) {
4880                updateOomAdjLocked();
4881            }
4882            if (doLowMem) {
4883                doLowMemReportIfNeededLocked(app);
4884            }
4885        } else if (app.pid != pid) {
4886            // A new process has already been started.
4887            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4888                    + ") has died and restarted (pid " + app.pid + ").");
4889            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4890        } else if (DEBUG_PROCESSES) {
4891            Slog.d(TAG, "Received spurious death notification for thread "
4892                    + thread.asBinder());
4893        }
4894    }
4895
4896    /**
4897     * If a stack trace dump file is configured, dump process stack traces.
4898     * @param clearTraces causes the dump file to be erased prior to the new
4899     *    traces being written, if true; when false, the new traces will be
4900     *    appended to any existing file content.
4901     * @param firstPids of dalvik VM processes to dump stack traces for first
4902     * @param lastPids of dalvik VM processes to dump stack traces for last
4903     * @param nativeProcs optional list of native process names to dump stack crawls
4904     * @return file containing stack traces, or null if no dump file is configured
4905     */
4906    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4907            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4908        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4909        if (tracesPath == null || tracesPath.length() == 0) {
4910            return null;
4911        }
4912
4913        File tracesFile = new File(tracesPath);
4914        try {
4915            File tracesDir = tracesFile.getParentFile();
4916            if (!tracesDir.exists()) {
4917                tracesDir.mkdirs();
4918                if (!SELinux.restorecon(tracesDir)) {
4919                    return null;
4920                }
4921            }
4922            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4923
4924            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4925            tracesFile.createNewFile();
4926            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4927        } catch (IOException e) {
4928            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4929            return null;
4930        }
4931
4932        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4933        return tracesFile;
4934    }
4935
4936    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4937            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4938        // Use a FileObserver to detect when traces finish writing.
4939        // The order of traces is considered important to maintain for legibility.
4940        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4941            @Override
4942            public synchronized void onEvent(int event, String path) { notify(); }
4943        };
4944
4945        try {
4946            observer.startWatching();
4947
4948            // First collect all of the stacks of the most important pids.
4949            if (firstPids != null) {
4950                try {
4951                    int num = firstPids.size();
4952                    for (int i = 0; i < num; i++) {
4953                        synchronized (observer) {
4954                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4955                            observer.wait(200);  // Wait for write-close, give up after 200msec
4956                        }
4957                    }
4958                } catch (InterruptedException e) {
4959                    Log.wtf(TAG, e);
4960                }
4961            }
4962
4963            // Next collect the stacks of the native pids
4964            if (nativeProcs != null) {
4965                int[] pids = Process.getPidsForCommands(nativeProcs);
4966                if (pids != null) {
4967                    for (int pid : pids) {
4968                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4969                    }
4970                }
4971            }
4972
4973            // Lastly, measure CPU usage.
4974            if (processCpuTracker != null) {
4975                processCpuTracker.init();
4976                System.gc();
4977                processCpuTracker.update();
4978                try {
4979                    synchronized (processCpuTracker) {
4980                        processCpuTracker.wait(500); // measure over 1/2 second.
4981                    }
4982                } catch (InterruptedException e) {
4983                }
4984                processCpuTracker.update();
4985
4986                // We'll take the stack crawls of just the top apps using CPU.
4987                final int N = processCpuTracker.countWorkingStats();
4988                int numProcs = 0;
4989                for (int i=0; i<N && numProcs<5; i++) {
4990                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4991                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4992                        numProcs++;
4993                        try {
4994                            synchronized (observer) {
4995                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4996                                observer.wait(200);  // Wait for write-close, give up after 200msec
4997                            }
4998                        } catch (InterruptedException e) {
4999                            Log.wtf(TAG, e);
5000                        }
5001
5002                    }
5003                }
5004            }
5005        } finally {
5006            observer.stopWatching();
5007        }
5008    }
5009
5010    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5011        if (true || IS_USER_BUILD) {
5012            return;
5013        }
5014        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5015        if (tracesPath == null || tracesPath.length() == 0) {
5016            return;
5017        }
5018
5019        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5020        StrictMode.allowThreadDiskWrites();
5021        try {
5022            final File tracesFile = new File(tracesPath);
5023            final File tracesDir = tracesFile.getParentFile();
5024            final File tracesTmp = new File(tracesDir, "__tmp__");
5025            try {
5026                if (!tracesDir.exists()) {
5027                    tracesDir.mkdirs();
5028                    if (!SELinux.restorecon(tracesDir.getPath())) {
5029                        return;
5030                    }
5031                }
5032                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5033
5034                if (tracesFile.exists()) {
5035                    tracesTmp.delete();
5036                    tracesFile.renameTo(tracesTmp);
5037                }
5038                StringBuilder sb = new StringBuilder();
5039                Time tobj = new Time();
5040                tobj.set(System.currentTimeMillis());
5041                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5042                sb.append(": ");
5043                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5044                sb.append(" since ");
5045                sb.append(msg);
5046                FileOutputStream fos = new FileOutputStream(tracesFile);
5047                fos.write(sb.toString().getBytes());
5048                if (app == null) {
5049                    fos.write("\n*** No application process!".getBytes());
5050                }
5051                fos.close();
5052                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5053            } catch (IOException e) {
5054                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5055                return;
5056            }
5057
5058            if (app != null) {
5059                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5060                firstPids.add(app.pid);
5061                dumpStackTraces(tracesPath, firstPids, null, null, null);
5062            }
5063
5064            File lastTracesFile = null;
5065            File curTracesFile = null;
5066            for (int i=9; i>=0; i--) {
5067                String name = String.format(Locale.US, "slow%02d.txt", i);
5068                curTracesFile = new File(tracesDir, name);
5069                if (curTracesFile.exists()) {
5070                    if (lastTracesFile != null) {
5071                        curTracesFile.renameTo(lastTracesFile);
5072                    } else {
5073                        curTracesFile.delete();
5074                    }
5075                }
5076                lastTracesFile = curTracesFile;
5077            }
5078            tracesFile.renameTo(curTracesFile);
5079            if (tracesTmp.exists()) {
5080                tracesTmp.renameTo(tracesFile);
5081            }
5082        } finally {
5083            StrictMode.setThreadPolicy(oldPolicy);
5084        }
5085    }
5086
5087    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5088            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5089        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5090        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5091
5092        if (mController != null) {
5093            try {
5094                // 0 == continue, -1 = kill process immediately
5095                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5096                if (res < 0 && app.pid != MY_PID) {
5097                    app.kill("anr", true);
5098                }
5099            } catch (RemoteException e) {
5100                mController = null;
5101                Watchdog.getInstance().setActivityController(null);
5102            }
5103        }
5104
5105        long anrTime = SystemClock.uptimeMillis();
5106        if (MONITOR_CPU_USAGE) {
5107            updateCpuStatsNow();
5108        }
5109
5110        synchronized (this) {
5111            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5112            if (mShuttingDown) {
5113                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5114                return;
5115            } else if (app.notResponding) {
5116                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5117                return;
5118            } else if (app.crashing) {
5119                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5120                return;
5121            }
5122
5123            // In case we come through here for the same app before completing
5124            // this one, mark as anring now so we will bail out.
5125            app.notResponding = true;
5126
5127            // Log the ANR to the event log.
5128            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5129                    app.processName, app.info.flags, annotation);
5130
5131            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5132            firstPids.add(app.pid);
5133
5134            int parentPid = app.pid;
5135            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5136            if (parentPid != app.pid) firstPids.add(parentPid);
5137
5138            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5139
5140            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5141                ProcessRecord r = mLruProcesses.get(i);
5142                if (r != null && r.thread != null) {
5143                    int pid = r.pid;
5144                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5145                        if (r.persistent) {
5146                            firstPids.add(pid);
5147                        } else {
5148                            lastPids.put(pid, Boolean.TRUE);
5149                        }
5150                    }
5151                }
5152            }
5153        }
5154
5155        // Log the ANR to the main log.
5156        StringBuilder info = new StringBuilder();
5157        info.setLength(0);
5158        info.append("ANR in ").append(app.processName);
5159        if (activity != null && activity.shortComponentName != null) {
5160            info.append(" (").append(activity.shortComponentName).append(")");
5161        }
5162        info.append("\n");
5163        info.append("PID: ").append(app.pid).append("\n");
5164        if (annotation != null) {
5165            info.append("Reason: ").append(annotation).append("\n");
5166        }
5167        if (parent != null && parent != activity) {
5168            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5169        }
5170
5171        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5172
5173        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5174                NATIVE_STACKS_OF_INTEREST);
5175
5176        String cpuInfo = null;
5177        if (MONITOR_CPU_USAGE) {
5178            updateCpuStatsNow();
5179            synchronized (mProcessCpuTracker) {
5180                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5181            }
5182            info.append(processCpuTracker.printCurrentLoad());
5183            info.append(cpuInfo);
5184        }
5185
5186        info.append(processCpuTracker.printCurrentState(anrTime));
5187
5188        Slog.e(TAG, info.toString());
5189        if (tracesFile == null) {
5190            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5191            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5192        }
5193
5194        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5195                cpuInfo, tracesFile, null);
5196
5197        if (mController != null) {
5198            try {
5199                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5200                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5201                if (res != 0) {
5202                    if (res < 0 && app.pid != MY_PID) {
5203                        app.kill("anr", true);
5204                    } else {
5205                        synchronized (this) {
5206                            mServices.scheduleServiceTimeoutLocked(app);
5207                        }
5208                    }
5209                    return;
5210                }
5211            } catch (RemoteException e) {
5212                mController = null;
5213                Watchdog.getInstance().setActivityController(null);
5214            }
5215        }
5216
5217        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5218        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5219                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5220
5221        synchronized (this) {
5222            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5223                app.kill("bg anr", true);
5224                return;
5225            }
5226
5227            // Set the app's notResponding state, and look up the errorReportReceiver
5228            makeAppNotRespondingLocked(app,
5229                    activity != null ? activity.shortComponentName : null,
5230                    annotation != null ? "ANR " + annotation : "ANR",
5231                    info.toString());
5232
5233            // Bring up the infamous App Not Responding dialog
5234            Message msg = Message.obtain();
5235            HashMap<String, Object> map = new HashMap<String, Object>();
5236            msg.what = SHOW_NOT_RESPONDING_MSG;
5237            msg.obj = map;
5238            msg.arg1 = aboveSystem ? 1 : 0;
5239            map.put("app", app);
5240            if (activity != null) {
5241                map.put("activity", activity);
5242            }
5243
5244            mHandler.sendMessage(msg);
5245        }
5246    }
5247
5248    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5249        if (!mLaunchWarningShown) {
5250            mLaunchWarningShown = true;
5251            mHandler.post(new Runnable() {
5252                @Override
5253                public void run() {
5254                    synchronized (ActivityManagerService.this) {
5255                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5256                        d.show();
5257                        mHandler.postDelayed(new Runnable() {
5258                            @Override
5259                            public void run() {
5260                                synchronized (ActivityManagerService.this) {
5261                                    d.dismiss();
5262                                    mLaunchWarningShown = false;
5263                                }
5264                            }
5265                        }, 4000);
5266                    }
5267                }
5268            });
5269        }
5270    }
5271
5272    @Override
5273    public boolean clearApplicationUserData(final String packageName,
5274            final IPackageDataObserver observer, int userId) {
5275        enforceNotIsolatedCaller("clearApplicationUserData");
5276        int uid = Binder.getCallingUid();
5277        int pid = Binder.getCallingPid();
5278        userId = handleIncomingUser(pid, uid,
5279                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5280        long callingId = Binder.clearCallingIdentity();
5281        try {
5282            IPackageManager pm = AppGlobals.getPackageManager();
5283            int pkgUid = -1;
5284            synchronized(this) {
5285                try {
5286                    pkgUid = pm.getPackageUid(packageName, userId);
5287                } catch (RemoteException e) {
5288                }
5289                if (pkgUid == -1) {
5290                    Slog.w(TAG, "Invalid packageName: " + packageName);
5291                    if (observer != null) {
5292                        try {
5293                            observer.onRemoveCompleted(packageName, false);
5294                        } catch (RemoteException e) {
5295                            Slog.i(TAG, "Observer no longer exists.");
5296                        }
5297                    }
5298                    return false;
5299                }
5300                if (uid == pkgUid || checkComponentPermission(
5301                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5302                        pid, uid, -1, true)
5303                        == PackageManager.PERMISSION_GRANTED) {
5304                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5305                } else {
5306                    throw new SecurityException("PID " + pid + " does not have permission "
5307                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5308                                    + " of package " + packageName);
5309                }
5310
5311                // Remove all tasks match the cleared application package and user
5312                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5313                    final TaskRecord tr = mRecentTasks.get(i);
5314                    final String taskPackageName =
5315                            tr.getBaseIntent().getComponent().getPackageName();
5316                    if (tr.userId != userId) continue;
5317                    if (!taskPackageName.equals(packageName)) continue;
5318                    removeTaskByIdLocked(tr.taskId, 0);
5319                }
5320            }
5321
5322            try {
5323                // Clear application user data
5324                pm.clearApplicationUserData(packageName, observer, userId);
5325
5326                synchronized(this) {
5327                    // Remove all permissions granted from/to this package
5328                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5329                }
5330
5331                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5332                        Uri.fromParts("package", packageName, null));
5333                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5334                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5335                        null, null, 0, null, null, null, false, false, userId);
5336            } catch (RemoteException e) {
5337            }
5338        } finally {
5339            Binder.restoreCallingIdentity(callingId);
5340        }
5341        return true;
5342    }
5343
5344    @Override
5345    public void killBackgroundProcesses(final String packageName, int userId) {
5346        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5347                != PackageManager.PERMISSION_GRANTED &&
5348                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5349                        != PackageManager.PERMISSION_GRANTED) {
5350            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5351                    + Binder.getCallingPid()
5352                    + ", uid=" + Binder.getCallingUid()
5353                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5354            Slog.w(TAG, msg);
5355            throw new SecurityException(msg);
5356        }
5357
5358        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5359                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5360        long callingId = Binder.clearCallingIdentity();
5361        try {
5362            IPackageManager pm = AppGlobals.getPackageManager();
5363            synchronized(this) {
5364                int appId = -1;
5365                try {
5366                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5367                } catch (RemoteException e) {
5368                }
5369                if (appId == -1) {
5370                    Slog.w(TAG, "Invalid packageName: " + packageName);
5371                    return;
5372                }
5373                killPackageProcessesLocked(packageName, appId, userId,
5374                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5375            }
5376        } finally {
5377            Binder.restoreCallingIdentity(callingId);
5378        }
5379    }
5380
5381    @Override
5382    public void killAllBackgroundProcesses() {
5383        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5384                != PackageManager.PERMISSION_GRANTED) {
5385            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5386                    + Binder.getCallingPid()
5387                    + ", uid=" + Binder.getCallingUid()
5388                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5389            Slog.w(TAG, msg);
5390            throw new SecurityException(msg);
5391        }
5392
5393        long callingId = Binder.clearCallingIdentity();
5394        try {
5395            synchronized(this) {
5396                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5397                final int NP = mProcessNames.getMap().size();
5398                for (int ip=0; ip<NP; ip++) {
5399                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5400                    final int NA = apps.size();
5401                    for (int ia=0; ia<NA; ia++) {
5402                        ProcessRecord app = apps.valueAt(ia);
5403                        if (app.persistent) {
5404                            // we don't kill persistent processes
5405                            continue;
5406                        }
5407                        if (app.removed) {
5408                            procs.add(app);
5409                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5410                            app.removed = true;
5411                            procs.add(app);
5412                        }
5413                    }
5414                }
5415
5416                int N = procs.size();
5417                for (int i=0; i<N; i++) {
5418                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5419                }
5420                mAllowLowerMemLevel = true;
5421                updateOomAdjLocked();
5422                doLowMemReportIfNeededLocked(null);
5423            }
5424        } finally {
5425            Binder.restoreCallingIdentity(callingId);
5426        }
5427    }
5428
5429    @Override
5430    public void forceStopPackage(final String packageName, int userId) {
5431        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5432                != PackageManager.PERMISSION_GRANTED) {
5433            String msg = "Permission Denial: forceStopPackage() from pid="
5434                    + Binder.getCallingPid()
5435                    + ", uid=" + Binder.getCallingUid()
5436                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5437            Slog.w(TAG, msg);
5438            throw new SecurityException(msg);
5439        }
5440        final int callingPid = Binder.getCallingPid();
5441        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5442                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5443        long callingId = Binder.clearCallingIdentity();
5444        try {
5445            IPackageManager pm = AppGlobals.getPackageManager();
5446            synchronized(this) {
5447                int[] users = userId == UserHandle.USER_ALL
5448                        ? getUsersLocked() : new int[] { userId };
5449                for (int user : users) {
5450                    int pkgUid = -1;
5451                    try {
5452                        pkgUid = pm.getPackageUid(packageName, user);
5453                    } catch (RemoteException e) {
5454                    }
5455                    if (pkgUid == -1) {
5456                        Slog.w(TAG, "Invalid packageName: " + packageName);
5457                        continue;
5458                    }
5459                    try {
5460                        pm.setPackageStoppedState(packageName, true, user);
5461                    } catch (RemoteException e) {
5462                    } catch (IllegalArgumentException e) {
5463                        Slog.w(TAG, "Failed trying to unstop package "
5464                                + packageName + ": " + e);
5465                    }
5466                    if (isUserRunningLocked(user, false)) {
5467                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5468                    }
5469                }
5470            }
5471        } finally {
5472            Binder.restoreCallingIdentity(callingId);
5473        }
5474    }
5475
5476    @Override
5477    public void addPackageDependency(String packageName) {
5478        synchronized (this) {
5479            int callingPid = Binder.getCallingPid();
5480            if (callingPid == Process.myPid()) {
5481                //  Yeah, um, no.
5482                Slog.w(TAG, "Can't addPackageDependency on system process");
5483                return;
5484            }
5485            ProcessRecord proc;
5486            synchronized (mPidsSelfLocked) {
5487                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5488            }
5489            if (proc != null) {
5490                if (proc.pkgDeps == null) {
5491                    proc.pkgDeps = new ArraySet<String>(1);
5492                }
5493                proc.pkgDeps.add(packageName);
5494            }
5495        }
5496    }
5497
5498    /*
5499     * The pkg name and app id have to be specified.
5500     */
5501    @Override
5502    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5503        if (pkg == null) {
5504            return;
5505        }
5506        // Make sure the uid is valid.
5507        if (appid < 0) {
5508            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5509            return;
5510        }
5511        int callerUid = Binder.getCallingUid();
5512        // Only the system server can kill an application
5513        if (callerUid == Process.SYSTEM_UID) {
5514            // Post an aysnc message to kill the application
5515            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5516            msg.arg1 = appid;
5517            msg.arg2 = 0;
5518            Bundle bundle = new Bundle();
5519            bundle.putString("pkg", pkg);
5520            bundle.putString("reason", reason);
5521            msg.obj = bundle;
5522            mHandler.sendMessage(msg);
5523        } else {
5524            throw new SecurityException(callerUid + " cannot kill pkg: " +
5525                    pkg);
5526        }
5527    }
5528
5529    @Override
5530    public void closeSystemDialogs(String reason) {
5531        enforceNotIsolatedCaller("closeSystemDialogs");
5532
5533        final int pid = Binder.getCallingPid();
5534        final int uid = Binder.getCallingUid();
5535        final long origId = Binder.clearCallingIdentity();
5536        try {
5537            synchronized (this) {
5538                // Only allow this from foreground processes, so that background
5539                // applications can't abuse it to prevent system UI from being shown.
5540                if (uid >= Process.FIRST_APPLICATION_UID) {
5541                    ProcessRecord proc;
5542                    synchronized (mPidsSelfLocked) {
5543                        proc = mPidsSelfLocked.get(pid);
5544                    }
5545                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5546                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5547                                + " from background process " + proc);
5548                        return;
5549                    }
5550                }
5551                closeSystemDialogsLocked(reason);
5552            }
5553        } finally {
5554            Binder.restoreCallingIdentity(origId);
5555        }
5556    }
5557
5558    void closeSystemDialogsLocked(String reason) {
5559        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5560        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5561                | Intent.FLAG_RECEIVER_FOREGROUND);
5562        if (reason != null) {
5563            intent.putExtra("reason", reason);
5564        }
5565        mWindowManager.closeSystemDialogs(reason);
5566
5567        mStackSupervisor.closeSystemDialogsLocked();
5568
5569        broadcastIntentLocked(null, null, intent, null,
5570                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5571                Process.SYSTEM_UID, UserHandle.USER_ALL);
5572    }
5573
5574    @Override
5575    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5576        enforceNotIsolatedCaller("getProcessMemoryInfo");
5577        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5578        for (int i=pids.length-1; i>=0; i--) {
5579            ProcessRecord proc;
5580            int oomAdj;
5581            synchronized (this) {
5582                synchronized (mPidsSelfLocked) {
5583                    proc = mPidsSelfLocked.get(pids[i]);
5584                    oomAdj = proc != null ? proc.setAdj : 0;
5585                }
5586            }
5587            infos[i] = new Debug.MemoryInfo();
5588            Debug.getMemoryInfo(pids[i], infos[i]);
5589            if (proc != null) {
5590                synchronized (this) {
5591                    if (proc.thread != null && proc.setAdj == oomAdj) {
5592                        // Record this for posterity if the process has been stable.
5593                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5594                                infos[i].getTotalUss(), false, proc.pkgList);
5595                    }
5596                }
5597            }
5598        }
5599        return infos;
5600    }
5601
5602    @Override
5603    public long[] getProcessPss(int[] pids) {
5604        enforceNotIsolatedCaller("getProcessPss");
5605        long[] pss = new long[pids.length];
5606        for (int i=pids.length-1; i>=0; i--) {
5607            ProcessRecord proc;
5608            int oomAdj;
5609            synchronized (this) {
5610                synchronized (mPidsSelfLocked) {
5611                    proc = mPidsSelfLocked.get(pids[i]);
5612                    oomAdj = proc != null ? proc.setAdj : 0;
5613                }
5614            }
5615            long[] tmpUss = new long[1];
5616            pss[i] = Debug.getPss(pids[i], tmpUss);
5617            if (proc != null) {
5618                synchronized (this) {
5619                    if (proc.thread != null && proc.setAdj == oomAdj) {
5620                        // Record this for posterity if the process has been stable.
5621                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5622                    }
5623                }
5624            }
5625        }
5626        return pss;
5627    }
5628
5629    @Override
5630    public void killApplicationProcess(String processName, int uid) {
5631        if (processName == null) {
5632            return;
5633        }
5634
5635        int callerUid = Binder.getCallingUid();
5636        // Only the system server can kill an application
5637        if (callerUid == Process.SYSTEM_UID) {
5638            synchronized (this) {
5639                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5640                if (app != null && app.thread != null) {
5641                    try {
5642                        app.thread.scheduleSuicide();
5643                    } catch (RemoteException e) {
5644                        // If the other end already died, then our work here is done.
5645                    }
5646                } else {
5647                    Slog.w(TAG, "Process/uid not found attempting kill of "
5648                            + processName + " / " + uid);
5649                }
5650            }
5651        } else {
5652            throw new SecurityException(callerUid + " cannot kill app process: " +
5653                    processName);
5654        }
5655    }
5656
5657    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5658        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5659                false, true, false, false, UserHandle.getUserId(uid), reason);
5660        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5661                Uri.fromParts("package", packageName, null));
5662        if (!mProcessesReady) {
5663            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5664                    | Intent.FLAG_RECEIVER_FOREGROUND);
5665        }
5666        intent.putExtra(Intent.EXTRA_UID, uid);
5667        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5668        broadcastIntentLocked(null, null, intent,
5669                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5670                false, false,
5671                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5672    }
5673
5674    private void forceStopUserLocked(int userId, String reason) {
5675        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5676        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5677        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5678                | Intent.FLAG_RECEIVER_FOREGROUND);
5679        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5680        broadcastIntentLocked(null, null, intent,
5681                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5682                false, false,
5683                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5684    }
5685
5686    private final boolean killPackageProcessesLocked(String packageName, int appId,
5687            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5688            boolean doit, boolean evenPersistent, String reason) {
5689        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5690
5691        // Remove all processes this package may have touched: all with the
5692        // same UID (except for the system or root user), and all whose name
5693        // matches the package name.
5694        final int NP = mProcessNames.getMap().size();
5695        for (int ip=0; ip<NP; ip++) {
5696            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5697            final int NA = apps.size();
5698            for (int ia=0; ia<NA; ia++) {
5699                ProcessRecord app = apps.valueAt(ia);
5700                if (app.persistent && !evenPersistent) {
5701                    // we don't kill persistent processes
5702                    continue;
5703                }
5704                if (app.removed) {
5705                    if (doit) {
5706                        procs.add(app);
5707                    }
5708                    continue;
5709                }
5710
5711                // Skip process if it doesn't meet our oom adj requirement.
5712                if (app.setAdj < minOomAdj) {
5713                    continue;
5714                }
5715
5716                // If no package is specified, we call all processes under the
5717                // give user id.
5718                if (packageName == null) {
5719                    if (app.userId != userId) {
5720                        continue;
5721                    }
5722                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5723                        continue;
5724                    }
5725                // Package has been specified, we want to hit all processes
5726                // that match it.  We need to qualify this by the processes
5727                // that are running under the specified app and user ID.
5728                } else {
5729                    final boolean isDep = app.pkgDeps != null
5730                            && app.pkgDeps.contains(packageName);
5731                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5732                        continue;
5733                    }
5734                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5735                        continue;
5736                    }
5737                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5738                        continue;
5739                    }
5740                }
5741
5742                // Process has passed all conditions, kill it!
5743                if (!doit) {
5744                    return true;
5745                }
5746                app.removed = true;
5747                procs.add(app);
5748            }
5749        }
5750
5751        int N = procs.size();
5752        for (int i=0; i<N; i++) {
5753            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5754        }
5755        updateOomAdjLocked();
5756        return N > 0;
5757    }
5758
5759    private final boolean forceStopPackageLocked(String name, int appId,
5760            boolean callerWillRestart, boolean purgeCache, boolean doit,
5761            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5762        int i;
5763        int N;
5764
5765        if (userId == UserHandle.USER_ALL && name == null) {
5766            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5767        }
5768
5769        if (appId < 0 && name != null) {
5770            try {
5771                appId = UserHandle.getAppId(
5772                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5773            } catch (RemoteException e) {
5774            }
5775        }
5776
5777        if (doit) {
5778            if (name != null) {
5779                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5780                        + " user=" + userId + ": " + reason);
5781            } else {
5782                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5783            }
5784
5785            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5786            for (int ip=pmap.size()-1; ip>=0; ip--) {
5787                SparseArray<Long> ba = pmap.valueAt(ip);
5788                for (i=ba.size()-1; i>=0; i--) {
5789                    boolean remove = false;
5790                    final int entUid = ba.keyAt(i);
5791                    if (name != null) {
5792                        if (userId == UserHandle.USER_ALL) {
5793                            if (UserHandle.getAppId(entUid) == appId) {
5794                                remove = true;
5795                            }
5796                        } else {
5797                            if (entUid == UserHandle.getUid(userId, appId)) {
5798                                remove = true;
5799                            }
5800                        }
5801                    } else if (UserHandle.getUserId(entUid) == userId) {
5802                        remove = true;
5803                    }
5804                    if (remove) {
5805                        ba.removeAt(i);
5806                    }
5807                }
5808                if (ba.size() == 0) {
5809                    pmap.removeAt(ip);
5810                }
5811            }
5812        }
5813
5814        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5815                -100, callerWillRestart, true, doit, evenPersistent,
5816                name == null ? ("stop user " + userId) : ("stop " + name));
5817
5818        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5819            if (!doit) {
5820                return true;
5821            }
5822            didSomething = true;
5823        }
5824
5825        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5826            if (!doit) {
5827                return true;
5828            }
5829            didSomething = true;
5830        }
5831
5832        if (name == null) {
5833            // Remove all sticky broadcasts from this user.
5834            mStickyBroadcasts.remove(userId);
5835        }
5836
5837        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5838        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5839                userId, providers)) {
5840            if (!doit) {
5841                return true;
5842            }
5843            didSomething = true;
5844        }
5845        N = providers.size();
5846        for (i=0; i<N; i++) {
5847            removeDyingProviderLocked(null, providers.get(i), true);
5848        }
5849
5850        // Remove transient permissions granted from/to this package/user
5851        removeUriPermissionsForPackageLocked(name, userId, false);
5852
5853        if (name == null || uninstalling) {
5854            // Remove pending intents.  For now we only do this when force
5855            // stopping users, because we have some problems when doing this
5856            // for packages -- app widgets are not currently cleaned up for
5857            // such packages, so they can be left with bad pending intents.
5858            if (mIntentSenderRecords.size() > 0) {
5859                Iterator<WeakReference<PendingIntentRecord>> it
5860                        = mIntentSenderRecords.values().iterator();
5861                while (it.hasNext()) {
5862                    WeakReference<PendingIntentRecord> wpir = it.next();
5863                    if (wpir == null) {
5864                        it.remove();
5865                        continue;
5866                    }
5867                    PendingIntentRecord pir = wpir.get();
5868                    if (pir == null) {
5869                        it.remove();
5870                        continue;
5871                    }
5872                    if (name == null) {
5873                        // Stopping user, remove all objects for the user.
5874                        if (pir.key.userId != userId) {
5875                            // Not the same user, skip it.
5876                            continue;
5877                        }
5878                    } else {
5879                        if (UserHandle.getAppId(pir.uid) != appId) {
5880                            // Different app id, skip it.
5881                            continue;
5882                        }
5883                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5884                            // Different user, skip it.
5885                            continue;
5886                        }
5887                        if (!pir.key.packageName.equals(name)) {
5888                            // Different package, skip it.
5889                            continue;
5890                        }
5891                    }
5892                    if (!doit) {
5893                        return true;
5894                    }
5895                    didSomething = true;
5896                    it.remove();
5897                    pir.canceled = true;
5898                    if (pir.key.activity != null) {
5899                        pir.key.activity.pendingResults.remove(pir.ref);
5900                    }
5901                }
5902            }
5903        }
5904
5905        if (doit) {
5906            if (purgeCache && name != null) {
5907                AttributeCache ac = AttributeCache.instance();
5908                if (ac != null) {
5909                    ac.removePackage(name);
5910                }
5911            }
5912            if (mBooted) {
5913                mStackSupervisor.resumeTopActivitiesLocked();
5914                mStackSupervisor.scheduleIdleLocked();
5915            }
5916        }
5917
5918        return didSomething;
5919    }
5920
5921    private final boolean removeProcessLocked(ProcessRecord app,
5922            boolean callerWillRestart, boolean allowRestart, String reason) {
5923        final String name = app.processName;
5924        final int uid = app.uid;
5925        if (DEBUG_PROCESSES) Slog.d(
5926            TAG, "Force removing proc " + app.toShortString() + " (" + name
5927            + "/" + uid + ")");
5928
5929        mProcessNames.remove(name, uid);
5930        mIsolatedProcesses.remove(app.uid);
5931        if (mHeavyWeightProcess == app) {
5932            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5933                    mHeavyWeightProcess.userId, 0));
5934            mHeavyWeightProcess = null;
5935        }
5936        boolean needRestart = false;
5937        if (app.pid > 0 && app.pid != MY_PID) {
5938            int pid = app.pid;
5939            synchronized (mPidsSelfLocked) {
5940                mPidsSelfLocked.remove(pid);
5941                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5942            }
5943            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5944            if (app.isolated) {
5945                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5946            }
5947            app.kill(reason, true);
5948            handleAppDiedLocked(app, true, allowRestart);
5949            removeLruProcessLocked(app);
5950
5951            if (app.persistent && !app.isolated) {
5952                if (!callerWillRestart) {
5953                    addAppLocked(app.info, false, null /* ABI override */);
5954                } else {
5955                    needRestart = true;
5956                }
5957            }
5958        } else {
5959            mRemovedProcesses.add(app);
5960        }
5961
5962        return needRestart;
5963    }
5964
5965    private final void processStartTimedOutLocked(ProcessRecord app) {
5966        final int pid = app.pid;
5967        boolean gone = false;
5968        synchronized (mPidsSelfLocked) {
5969            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5970            if (knownApp != null && knownApp.thread == null) {
5971                mPidsSelfLocked.remove(pid);
5972                gone = true;
5973            }
5974        }
5975
5976        if (gone) {
5977            Slog.w(TAG, "Process " + app + " failed to attach");
5978            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5979                    pid, app.uid, app.processName);
5980            mProcessNames.remove(app.processName, app.uid);
5981            mIsolatedProcesses.remove(app.uid);
5982            if (mHeavyWeightProcess == app) {
5983                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5984                        mHeavyWeightProcess.userId, 0));
5985                mHeavyWeightProcess = null;
5986            }
5987            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5988            if (app.isolated) {
5989                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5990            }
5991            // Take care of any launching providers waiting for this process.
5992            checkAppInLaunchingProvidersLocked(app, true);
5993            // Take care of any services that are waiting for the process.
5994            mServices.processStartTimedOutLocked(app);
5995            app.kill("start timeout", true);
5996            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5997                Slog.w(TAG, "Unattached app died before backup, skipping");
5998                try {
5999                    IBackupManager bm = IBackupManager.Stub.asInterface(
6000                            ServiceManager.getService(Context.BACKUP_SERVICE));
6001                    bm.agentDisconnected(app.info.packageName);
6002                } catch (RemoteException e) {
6003                    // Can't happen; the backup manager is local
6004                }
6005            }
6006            if (isPendingBroadcastProcessLocked(pid)) {
6007                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6008                skipPendingBroadcastLocked(pid);
6009            }
6010        } else {
6011            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6012        }
6013    }
6014
6015    private final boolean attachApplicationLocked(IApplicationThread thread,
6016            int pid) {
6017
6018        // Find the application record that is being attached...  either via
6019        // the pid if we are running in multiple processes, or just pull the
6020        // next app record if we are emulating process with anonymous threads.
6021        ProcessRecord app;
6022        if (pid != MY_PID && pid >= 0) {
6023            synchronized (mPidsSelfLocked) {
6024                app = mPidsSelfLocked.get(pid);
6025            }
6026        } else {
6027            app = null;
6028        }
6029
6030        if (app == null) {
6031            Slog.w(TAG, "No pending application record for pid " + pid
6032                    + " (IApplicationThread " + thread + "); dropping process");
6033            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6034            if (pid > 0 && pid != MY_PID) {
6035                Process.killProcessQuiet(pid);
6036                //TODO: Process.killProcessGroup(app.info.uid, pid);
6037            } else {
6038                try {
6039                    thread.scheduleExit();
6040                } catch (Exception e) {
6041                    // Ignore exceptions.
6042                }
6043            }
6044            return false;
6045        }
6046
6047        // If this application record is still attached to a previous
6048        // process, clean it up now.
6049        if (app.thread != null) {
6050            handleAppDiedLocked(app, true, true);
6051        }
6052
6053        // Tell the process all about itself.
6054
6055        if (localLOGV) Slog.v(
6056                TAG, "Binding process pid " + pid + " to record " + app);
6057
6058        final String processName = app.processName;
6059        try {
6060            AppDeathRecipient adr = new AppDeathRecipient(
6061                    app, pid, thread);
6062            thread.asBinder().linkToDeath(adr, 0);
6063            app.deathRecipient = adr;
6064        } catch (RemoteException e) {
6065            app.resetPackageList(mProcessStats);
6066            startProcessLocked(app, "link fail", processName);
6067            return false;
6068        }
6069
6070        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6071
6072        app.makeActive(thread, mProcessStats);
6073        app.curAdj = app.setAdj = -100;
6074        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6075        app.forcingToForeground = null;
6076        updateProcessForegroundLocked(app, false, false);
6077        app.hasShownUi = false;
6078        app.debugging = false;
6079        app.cached = false;
6080
6081        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6082
6083        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6084        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6085
6086        if (!normalMode) {
6087            Slog.i(TAG, "Launching preboot mode app: " + app);
6088        }
6089
6090        if (localLOGV) Slog.v(
6091            TAG, "New app record " + app
6092            + " thread=" + thread.asBinder() + " pid=" + pid);
6093        try {
6094            int testMode = IApplicationThread.DEBUG_OFF;
6095            if (mDebugApp != null && mDebugApp.equals(processName)) {
6096                testMode = mWaitForDebugger
6097                    ? IApplicationThread.DEBUG_WAIT
6098                    : IApplicationThread.DEBUG_ON;
6099                app.debugging = true;
6100                if (mDebugTransient) {
6101                    mDebugApp = mOrigDebugApp;
6102                    mWaitForDebugger = mOrigWaitForDebugger;
6103                }
6104            }
6105            String profileFile = app.instrumentationProfileFile;
6106            ParcelFileDescriptor profileFd = null;
6107            int samplingInterval = 0;
6108            boolean profileAutoStop = false;
6109            if (mProfileApp != null && mProfileApp.equals(processName)) {
6110                mProfileProc = app;
6111                profileFile = mProfileFile;
6112                profileFd = mProfileFd;
6113                samplingInterval = mSamplingInterval;
6114                profileAutoStop = mAutoStopProfiler;
6115            }
6116            boolean enableOpenGlTrace = false;
6117            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6118                enableOpenGlTrace = true;
6119                mOpenGlTraceApp = null;
6120            }
6121
6122            // If the app is being launched for restore or full backup, set it up specially
6123            boolean isRestrictedBackupMode = false;
6124            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6125                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6126                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6127                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6128            }
6129
6130            ensurePackageDexOpt(app.instrumentationInfo != null
6131                    ? app.instrumentationInfo.packageName
6132                    : app.info.packageName);
6133            if (app.instrumentationClass != null) {
6134                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6135            }
6136            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6137                    + processName + " with config " + mConfiguration);
6138            ApplicationInfo appInfo = app.instrumentationInfo != null
6139                    ? app.instrumentationInfo : app.info;
6140            app.compat = compatibilityInfoForPackageLocked(appInfo);
6141            if (profileFd != null) {
6142                profileFd = profileFd.dup();
6143            }
6144            ProfilerInfo profilerInfo = profileFile == null ? null
6145                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6146            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6147                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6148                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6149                    isRestrictedBackupMode || !normalMode, app.persistent,
6150                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6151                    mCoreSettingsObserver.getCoreSettingsLocked());
6152            updateLruProcessLocked(app, false, null);
6153            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6154        } catch (Exception e) {
6155            // todo: Yikes!  What should we do?  For now we will try to
6156            // start another process, but that could easily get us in
6157            // an infinite loop of restarting processes...
6158            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6159
6160            app.resetPackageList(mProcessStats);
6161            app.unlinkDeathRecipient();
6162            startProcessLocked(app, "bind fail", processName);
6163            return false;
6164        }
6165
6166        // Remove this record from the list of starting applications.
6167        mPersistentStartingProcesses.remove(app);
6168        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6169                "Attach application locked removing on hold: " + app);
6170        mProcessesOnHold.remove(app);
6171
6172        boolean badApp = false;
6173        boolean didSomething = false;
6174
6175        // See if the top visible activity is waiting to run in this process...
6176        if (normalMode) {
6177            try {
6178                if (mStackSupervisor.attachApplicationLocked(app)) {
6179                    didSomething = true;
6180                }
6181            } catch (Exception e) {
6182                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6183                badApp = true;
6184            }
6185        }
6186
6187        // Find any services that should be running in this process...
6188        if (!badApp) {
6189            try {
6190                didSomething |= mServices.attachApplicationLocked(app, processName);
6191            } catch (Exception e) {
6192                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6193                badApp = true;
6194            }
6195        }
6196
6197        // Check if a next-broadcast receiver is in this process...
6198        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6199            try {
6200                didSomething |= sendPendingBroadcastsLocked(app);
6201            } catch (Exception e) {
6202                // If the app died trying to launch the receiver we declare it 'bad'
6203                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6204                badApp = true;
6205            }
6206        }
6207
6208        // Check whether the next backup agent is in this process...
6209        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6210            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6211            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6212            try {
6213                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6214                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6215                        mBackupTarget.backupMode);
6216            } catch (Exception e) {
6217                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6218                badApp = true;
6219            }
6220        }
6221
6222        if (badApp) {
6223            app.kill("error during init", true);
6224            handleAppDiedLocked(app, false, true);
6225            return false;
6226        }
6227
6228        if (!didSomething) {
6229            updateOomAdjLocked();
6230        }
6231
6232        return true;
6233    }
6234
6235    @Override
6236    public final void attachApplication(IApplicationThread thread) {
6237        synchronized (this) {
6238            int callingPid = Binder.getCallingPid();
6239            final long origId = Binder.clearCallingIdentity();
6240            attachApplicationLocked(thread, callingPid);
6241            Binder.restoreCallingIdentity(origId);
6242        }
6243    }
6244
6245    @Override
6246    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6247        final long origId = Binder.clearCallingIdentity();
6248        synchronized (this) {
6249            ActivityStack stack = ActivityRecord.getStackLocked(token);
6250            if (stack != null) {
6251                ActivityRecord r =
6252                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6253                if (stopProfiling) {
6254                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6255                        try {
6256                            mProfileFd.close();
6257                        } catch (IOException e) {
6258                        }
6259                        clearProfilerLocked();
6260                    }
6261                }
6262            }
6263        }
6264        Binder.restoreCallingIdentity(origId);
6265    }
6266
6267    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6268        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6269                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6270    }
6271
6272    void enableScreenAfterBoot() {
6273        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6274                SystemClock.uptimeMillis());
6275        mWindowManager.enableScreenAfterBoot();
6276
6277        synchronized (this) {
6278            updateEventDispatchingLocked();
6279        }
6280    }
6281
6282    @Override
6283    public void showBootMessage(final CharSequence msg, final boolean always) {
6284        enforceNotIsolatedCaller("showBootMessage");
6285        mWindowManager.showBootMessage(msg, always);
6286    }
6287
6288    @Override
6289    public void keyguardWaitingForActivityDrawn() {
6290        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6291        final long token = Binder.clearCallingIdentity();
6292        try {
6293            synchronized (this) {
6294                if (DEBUG_LOCKSCREEN) logLockScreen("");
6295                mWindowManager.keyguardWaitingForActivityDrawn();
6296                if (mLockScreenShown) {
6297                    mLockScreenShown = false;
6298                    comeOutOfSleepIfNeededLocked();
6299                }
6300            }
6301        } finally {
6302            Binder.restoreCallingIdentity(token);
6303        }
6304    }
6305
6306    final void finishBooting() {
6307        synchronized (this) {
6308            if (!mBootAnimationComplete) {
6309                mCallFinishBooting = true;
6310                return;
6311            }
6312            mCallFinishBooting = false;
6313        }
6314
6315        // Register receivers to handle package update events
6316        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6317
6318        // Let system services know.
6319        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6320
6321        synchronized (this) {
6322            // Ensure that any processes we had put on hold are now started
6323            // up.
6324            final int NP = mProcessesOnHold.size();
6325            if (NP > 0) {
6326                ArrayList<ProcessRecord> procs =
6327                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6328                for (int ip=0; ip<NP; ip++) {
6329                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6330                            + procs.get(ip));
6331                    startProcessLocked(procs.get(ip), "on-hold", null);
6332                }
6333            }
6334
6335            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6336                // Start looking for apps that are abusing wake locks.
6337                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6338                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6339                // Tell anyone interested that we are done booting!
6340                SystemProperties.set("sys.boot_completed", "1");
6341
6342                // And trigger dev.bootcomplete if we are not showing encryption progress
6343                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6344                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6345                    SystemProperties.set("dev.bootcomplete", "1");
6346                }
6347                for (int i=0; i<mStartedUsers.size(); i++) {
6348                    UserStartedState uss = mStartedUsers.valueAt(i);
6349                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6350                        uss.mState = UserStartedState.STATE_RUNNING;
6351                        final int userId = mStartedUsers.keyAt(i);
6352                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6353                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6354                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6355                        broadcastIntentLocked(null, null, intent, null,
6356                                new IIntentReceiver.Stub() {
6357                                    @Override
6358                                    public void performReceive(Intent intent, int resultCode,
6359                                            String data, Bundle extras, boolean ordered,
6360                                            boolean sticky, int sendingUser) {
6361                                        synchronized (ActivityManagerService.this) {
6362                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6363                                                    true, false);
6364                                        }
6365                                    }
6366                                },
6367                                0, null, null,
6368                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6369                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6370                                userId);
6371                    }
6372                }
6373                scheduleStartProfilesLocked();
6374            }
6375        }
6376    }
6377
6378    @Override
6379    public void bootAnimationComplete() {
6380        final boolean callFinishBooting;
6381        synchronized (this) {
6382            callFinishBooting = mCallFinishBooting;
6383            mBootAnimationComplete = true;
6384        }
6385        if (callFinishBooting) {
6386            finishBooting();
6387        }
6388    }
6389
6390    final void ensureBootCompleted() {
6391        boolean booting;
6392        boolean enableScreen;
6393        synchronized (this) {
6394            booting = mBooting;
6395            mBooting = false;
6396            enableScreen = !mBooted;
6397            mBooted = true;
6398        }
6399
6400        if (booting) {
6401            finishBooting();
6402        }
6403
6404        if (enableScreen) {
6405            enableScreenAfterBoot();
6406        }
6407    }
6408
6409    @Override
6410    public final void activityResumed(IBinder token) {
6411        final long origId = Binder.clearCallingIdentity();
6412        synchronized(this) {
6413            ActivityStack stack = ActivityRecord.getStackLocked(token);
6414            if (stack != null) {
6415                ActivityRecord.activityResumedLocked(token);
6416            }
6417        }
6418        Binder.restoreCallingIdentity(origId);
6419    }
6420
6421    @Override
6422    public final void activityPaused(IBinder token) {
6423        final long origId = Binder.clearCallingIdentity();
6424        synchronized(this) {
6425            ActivityStack stack = ActivityRecord.getStackLocked(token);
6426            if (stack != null) {
6427                stack.activityPausedLocked(token, false);
6428            }
6429        }
6430        Binder.restoreCallingIdentity(origId);
6431    }
6432
6433    @Override
6434    public final void activityStopped(IBinder token, Bundle icicle,
6435            PersistableBundle persistentState, CharSequence description) {
6436        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6437
6438        // Refuse possible leaked file descriptors
6439        if (icicle != null && icicle.hasFileDescriptors()) {
6440            throw new IllegalArgumentException("File descriptors passed in Bundle");
6441        }
6442
6443        final long origId = Binder.clearCallingIdentity();
6444
6445        synchronized (this) {
6446            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6447            if (r != null) {
6448                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6449            }
6450        }
6451
6452        trimApplications();
6453
6454        Binder.restoreCallingIdentity(origId);
6455    }
6456
6457    @Override
6458    public final void activityDestroyed(IBinder token) {
6459        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6460        synchronized (this) {
6461            ActivityStack stack = ActivityRecord.getStackLocked(token);
6462            if (stack != null) {
6463                stack.activityDestroyedLocked(token);
6464            }
6465        }
6466    }
6467
6468    @Override
6469    public final void backgroundResourcesReleased(IBinder token) {
6470        final long origId = Binder.clearCallingIdentity();
6471        try {
6472            synchronized (this) {
6473                ActivityStack stack = ActivityRecord.getStackLocked(token);
6474                if (stack != null) {
6475                    stack.backgroundResourcesReleased(token);
6476                }
6477            }
6478        } finally {
6479            Binder.restoreCallingIdentity(origId);
6480        }
6481    }
6482
6483    @Override
6484    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6485        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6486    }
6487
6488    @Override
6489    public final void notifyEnterAnimationComplete(IBinder token) {
6490        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6491    }
6492
6493    @Override
6494    public String getCallingPackage(IBinder token) {
6495        synchronized (this) {
6496            ActivityRecord r = getCallingRecordLocked(token);
6497            return r != null ? r.info.packageName : null;
6498        }
6499    }
6500
6501    @Override
6502    public ComponentName getCallingActivity(IBinder token) {
6503        synchronized (this) {
6504            ActivityRecord r = getCallingRecordLocked(token);
6505            return r != null ? r.intent.getComponent() : null;
6506        }
6507    }
6508
6509    private ActivityRecord getCallingRecordLocked(IBinder token) {
6510        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6511        if (r == null) {
6512            return null;
6513        }
6514        return r.resultTo;
6515    }
6516
6517    @Override
6518    public ComponentName getActivityClassForToken(IBinder token) {
6519        synchronized(this) {
6520            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6521            if (r == null) {
6522                return null;
6523            }
6524            return r.intent.getComponent();
6525        }
6526    }
6527
6528    @Override
6529    public String getPackageForToken(IBinder token) {
6530        synchronized(this) {
6531            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6532            if (r == null) {
6533                return null;
6534            }
6535            return r.packageName;
6536        }
6537    }
6538
6539    @Override
6540    public IIntentSender getIntentSender(int type,
6541            String packageName, IBinder token, String resultWho,
6542            int requestCode, Intent[] intents, String[] resolvedTypes,
6543            int flags, Bundle options, int userId) {
6544        enforceNotIsolatedCaller("getIntentSender");
6545        // Refuse possible leaked file descriptors
6546        if (intents != null) {
6547            if (intents.length < 1) {
6548                throw new IllegalArgumentException("Intents array length must be >= 1");
6549            }
6550            for (int i=0; i<intents.length; i++) {
6551                Intent intent = intents[i];
6552                if (intent != null) {
6553                    if (intent.hasFileDescriptors()) {
6554                        throw new IllegalArgumentException("File descriptors passed in Intent");
6555                    }
6556                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6557                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6558                        throw new IllegalArgumentException(
6559                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6560                    }
6561                    intents[i] = new Intent(intent);
6562                }
6563            }
6564            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6565                throw new IllegalArgumentException(
6566                        "Intent array length does not match resolvedTypes length");
6567            }
6568        }
6569        if (options != null) {
6570            if (options.hasFileDescriptors()) {
6571                throw new IllegalArgumentException("File descriptors passed in options");
6572            }
6573        }
6574
6575        synchronized(this) {
6576            int callingUid = Binder.getCallingUid();
6577            int origUserId = userId;
6578            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6579                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6580                    ALLOW_NON_FULL, "getIntentSender", null);
6581            if (origUserId == UserHandle.USER_CURRENT) {
6582                // We don't want to evaluate this until the pending intent is
6583                // actually executed.  However, we do want to always do the
6584                // security checking for it above.
6585                userId = UserHandle.USER_CURRENT;
6586            }
6587            try {
6588                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6589                    int uid = AppGlobals.getPackageManager()
6590                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6591                    if (!UserHandle.isSameApp(callingUid, uid)) {
6592                        String msg = "Permission Denial: getIntentSender() from pid="
6593                            + Binder.getCallingPid()
6594                            + ", uid=" + Binder.getCallingUid()
6595                            + ", (need uid=" + uid + ")"
6596                            + " is not allowed to send as package " + packageName;
6597                        Slog.w(TAG, msg);
6598                        throw new SecurityException(msg);
6599                    }
6600                }
6601
6602                return getIntentSenderLocked(type, packageName, callingUid, userId,
6603                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6604
6605            } catch (RemoteException e) {
6606                throw new SecurityException(e);
6607            }
6608        }
6609    }
6610
6611    IIntentSender getIntentSenderLocked(int type, String packageName,
6612            int callingUid, int userId, IBinder token, String resultWho,
6613            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6614            Bundle options) {
6615        if (DEBUG_MU)
6616            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6617        ActivityRecord activity = null;
6618        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6619            activity = ActivityRecord.isInStackLocked(token);
6620            if (activity == null) {
6621                return null;
6622            }
6623            if (activity.finishing) {
6624                return null;
6625            }
6626        }
6627
6628        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6629        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6630        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6631        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6632                |PendingIntent.FLAG_UPDATE_CURRENT);
6633
6634        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6635                type, packageName, activity, resultWho,
6636                requestCode, intents, resolvedTypes, flags, options, userId);
6637        WeakReference<PendingIntentRecord> ref;
6638        ref = mIntentSenderRecords.get(key);
6639        PendingIntentRecord rec = ref != null ? ref.get() : null;
6640        if (rec != null) {
6641            if (!cancelCurrent) {
6642                if (updateCurrent) {
6643                    if (rec.key.requestIntent != null) {
6644                        rec.key.requestIntent.replaceExtras(intents != null ?
6645                                intents[intents.length - 1] : null);
6646                    }
6647                    if (intents != null) {
6648                        intents[intents.length-1] = rec.key.requestIntent;
6649                        rec.key.allIntents = intents;
6650                        rec.key.allResolvedTypes = resolvedTypes;
6651                    } else {
6652                        rec.key.allIntents = null;
6653                        rec.key.allResolvedTypes = null;
6654                    }
6655                }
6656                return rec;
6657            }
6658            rec.canceled = true;
6659            mIntentSenderRecords.remove(key);
6660        }
6661        if (noCreate) {
6662            return rec;
6663        }
6664        rec = new PendingIntentRecord(this, key, callingUid);
6665        mIntentSenderRecords.put(key, rec.ref);
6666        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6667            if (activity.pendingResults == null) {
6668                activity.pendingResults
6669                        = new HashSet<WeakReference<PendingIntentRecord>>();
6670            }
6671            activity.pendingResults.add(rec.ref);
6672        }
6673        return rec;
6674    }
6675
6676    @Override
6677    public void cancelIntentSender(IIntentSender sender) {
6678        if (!(sender instanceof PendingIntentRecord)) {
6679            return;
6680        }
6681        synchronized(this) {
6682            PendingIntentRecord rec = (PendingIntentRecord)sender;
6683            try {
6684                int uid = AppGlobals.getPackageManager()
6685                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6686                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6687                    String msg = "Permission Denial: cancelIntentSender() from pid="
6688                        + Binder.getCallingPid()
6689                        + ", uid=" + Binder.getCallingUid()
6690                        + " is not allowed to cancel packges "
6691                        + rec.key.packageName;
6692                    Slog.w(TAG, msg);
6693                    throw new SecurityException(msg);
6694                }
6695            } catch (RemoteException e) {
6696                throw new SecurityException(e);
6697            }
6698            cancelIntentSenderLocked(rec, true);
6699        }
6700    }
6701
6702    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6703        rec.canceled = true;
6704        mIntentSenderRecords.remove(rec.key);
6705        if (cleanActivity && rec.key.activity != null) {
6706            rec.key.activity.pendingResults.remove(rec.ref);
6707        }
6708    }
6709
6710    @Override
6711    public String getPackageForIntentSender(IIntentSender pendingResult) {
6712        if (!(pendingResult instanceof PendingIntentRecord)) {
6713            return null;
6714        }
6715        try {
6716            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6717            return res.key.packageName;
6718        } catch (ClassCastException e) {
6719        }
6720        return null;
6721    }
6722
6723    @Override
6724    public int getUidForIntentSender(IIntentSender sender) {
6725        if (sender instanceof PendingIntentRecord) {
6726            try {
6727                PendingIntentRecord res = (PendingIntentRecord)sender;
6728                return res.uid;
6729            } catch (ClassCastException e) {
6730            }
6731        }
6732        return -1;
6733    }
6734
6735    @Override
6736    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6737        if (!(pendingResult instanceof PendingIntentRecord)) {
6738            return false;
6739        }
6740        try {
6741            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6742            if (res.key.allIntents == null) {
6743                return false;
6744            }
6745            for (int i=0; i<res.key.allIntents.length; i++) {
6746                Intent intent = res.key.allIntents[i];
6747                if (intent.getPackage() != null && intent.getComponent() != null) {
6748                    return false;
6749                }
6750            }
6751            return true;
6752        } catch (ClassCastException e) {
6753        }
6754        return false;
6755    }
6756
6757    @Override
6758    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6759        if (!(pendingResult instanceof PendingIntentRecord)) {
6760            return false;
6761        }
6762        try {
6763            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6764            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6765                return true;
6766            }
6767            return false;
6768        } catch (ClassCastException e) {
6769        }
6770        return false;
6771    }
6772
6773    @Override
6774    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6775        if (!(pendingResult instanceof PendingIntentRecord)) {
6776            return null;
6777        }
6778        try {
6779            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6780            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6781        } catch (ClassCastException e) {
6782        }
6783        return null;
6784    }
6785
6786    @Override
6787    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6788        if (!(pendingResult instanceof PendingIntentRecord)) {
6789            return null;
6790        }
6791        try {
6792            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6793            Intent intent = res.key.requestIntent;
6794            if (intent != null) {
6795                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6796                        || res.lastTagPrefix.equals(prefix))) {
6797                    return res.lastTag;
6798                }
6799                res.lastTagPrefix = prefix;
6800                StringBuilder sb = new StringBuilder(128);
6801                if (prefix != null) {
6802                    sb.append(prefix);
6803                }
6804                if (intent.getAction() != null) {
6805                    sb.append(intent.getAction());
6806                } else if (intent.getComponent() != null) {
6807                    intent.getComponent().appendShortString(sb);
6808                } else {
6809                    sb.append("?");
6810                }
6811                return res.lastTag = sb.toString();
6812            }
6813        } catch (ClassCastException e) {
6814        }
6815        return null;
6816    }
6817
6818    @Override
6819    public void setProcessLimit(int max) {
6820        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6821                "setProcessLimit()");
6822        synchronized (this) {
6823            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6824            mProcessLimitOverride = max;
6825        }
6826        trimApplications();
6827    }
6828
6829    @Override
6830    public int getProcessLimit() {
6831        synchronized (this) {
6832            return mProcessLimitOverride;
6833        }
6834    }
6835
6836    void foregroundTokenDied(ForegroundToken token) {
6837        synchronized (ActivityManagerService.this) {
6838            synchronized (mPidsSelfLocked) {
6839                ForegroundToken cur
6840                    = mForegroundProcesses.get(token.pid);
6841                if (cur != token) {
6842                    return;
6843                }
6844                mForegroundProcesses.remove(token.pid);
6845                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6846                if (pr == null) {
6847                    return;
6848                }
6849                pr.forcingToForeground = null;
6850                updateProcessForegroundLocked(pr, false, false);
6851            }
6852            updateOomAdjLocked();
6853        }
6854    }
6855
6856    @Override
6857    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6858        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6859                "setProcessForeground()");
6860        synchronized(this) {
6861            boolean changed = false;
6862
6863            synchronized (mPidsSelfLocked) {
6864                ProcessRecord pr = mPidsSelfLocked.get(pid);
6865                if (pr == null && isForeground) {
6866                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6867                    return;
6868                }
6869                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6870                if (oldToken != null) {
6871                    oldToken.token.unlinkToDeath(oldToken, 0);
6872                    mForegroundProcesses.remove(pid);
6873                    if (pr != null) {
6874                        pr.forcingToForeground = null;
6875                    }
6876                    changed = true;
6877                }
6878                if (isForeground && token != null) {
6879                    ForegroundToken newToken = new ForegroundToken() {
6880                        @Override
6881                        public void binderDied() {
6882                            foregroundTokenDied(this);
6883                        }
6884                    };
6885                    newToken.pid = pid;
6886                    newToken.token = token;
6887                    try {
6888                        token.linkToDeath(newToken, 0);
6889                        mForegroundProcesses.put(pid, newToken);
6890                        pr.forcingToForeground = token;
6891                        changed = true;
6892                    } catch (RemoteException e) {
6893                        // If the process died while doing this, we will later
6894                        // do the cleanup with the process death link.
6895                    }
6896                }
6897            }
6898
6899            if (changed) {
6900                updateOomAdjLocked();
6901            }
6902        }
6903    }
6904
6905    // =========================================================
6906    // PERMISSIONS
6907    // =========================================================
6908
6909    static class PermissionController extends IPermissionController.Stub {
6910        ActivityManagerService mActivityManagerService;
6911        PermissionController(ActivityManagerService activityManagerService) {
6912            mActivityManagerService = activityManagerService;
6913        }
6914
6915        @Override
6916        public boolean checkPermission(String permission, int pid, int uid) {
6917            return mActivityManagerService.checkPermission(permission, pid,
6918                    uid) == PackageManager.PERMISSION_GRANTED;
6919        }
6920    }
6921
6922    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6923        @Override
6924        public int checkComponentPermission(String permission, int pid, int uid,
6925                int owningUid, boolean exported) {
6926            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6927                    owningUid, exported);
6928        }
6929
6930        @Override
6931        public Object getAMSLock() {
6932            return ActivityManagerService.this;
6933        }
6934    }
6935
6936    /**
6937     * This can be called with or without the global lock held.
6938     */
6939    int checkComponentPermission(String permission, int pid, int uid,
6940            int owningUid, boolean exported) {
6941        // We might be performing an operation on behalf of an indirect binder
6942        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6943        // client identity accordingly before proceeding.
6944        Identity tlsIdentity = sCallerIdentity.get();
6945        if (tlsIdentity != null) {
6946            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6947                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6948            uid = tlsIdentity.uid;
6949            pid = tlsIdentity.pid;
6950        }
6951
6952        if (pid == MY_PID) {
6953            return PackageManager.PERMISSION_GRANTED;
6954        }
6955
6956        return ActivityManager.checkComponentPermission(permission, uid,
6957                owningUid, exported);
6958    }
6959
6960    /**
6961     * As the only public entry point for permissions checking, this method
6962     * can enforce the semantic that requesting a check on a null global
6963     * permission is automatically denied.  (Internally a null permission
6964     * string is used when calling {@link #checkComponentPermission} in cases
6965     * when only uid-based security is needed.)
6966     *
6967     * This can be called with or without the global lock held.
6968     */
6969    @Override
6970    public int checkPermission(String permission, int pid, int uid) {
6971        if (permission == null) {
6972            return PackageManager.PERMISSION_DENIED;
6973        }
6974        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6975    }
6976
6977    /**
6978     * Binder IPC calls go through the public entry point.
6979     * This can be called with or without the global lock held.
6980     */
6981    int checkCallingPermission(String permission) {
6982        return checkPermission(permission,
6983                Binder.getCallingPid(),
6984                UserHandle.getAppId(Binder.getCallingUid()));
6985    }
6986
6987    /**
6988     * This can be called with or without the global lock held.
6989     */
6990    void enforceCallingPermission(String permission, String func) {
6991        if (checkCallingPermission(permission)
6992                == PackageManager.PERMISSION_GRANTED) {
6993            return;
6994        }
6995
6996        String msg = "Permission Denial: " + func + " from pid="
6997                + Binder.getCallingPid()
6998                + ", uid=" + Binder.getCallingUid()
6999                + " requires " + permission;
7000        Slog.w(TAG, msg);
7001        throw new SecurityException(msg);
7002    }
7003
7004    /**
7005     * Determine if UID is holding permissions required to access {@link Uri} in
7006     * the given {@link ProviderInfo}. Final permission checking is always done
7007     * in {@link ContentProvider}.
7008     */
7009    private final boolean checkHoldingPermissionsLocked(
7010            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7011        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7012                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7013        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7014            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7015                    != PERMISSION_GRANTED) {
7016                return false;
7017            }
7018        }
7019        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7020    }
7021
7022    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7023            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7024        if (pi.applicationInfo.uid == uid) {
7025            return true;
7026        } else if (!pi.exported) {
7027            return false;
7028        }
7029
7030        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7031        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7032        try {
7033            // check if target holds top-level <provider> permissions
7034            if (!readMet && pi.readPermission != null && considerUidPermissions
7035                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7036                readMet = true;
7037            }
7038            if (!writeMet && pi.writePermission != null && considerUidPermissions
7039                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7040                writeMet = true;
7041            }
7042
7043            // track if unprotected read/write is allowed; any denied
7044            // <path-permission> below removes this ability
7045            boolean allowDefaultRead = pi.readPermission == null;
7046            boolean allowDefaultWrite = pi.writePermission == null;
7047
7048            // check if target holds any <path-permission> that match uri
7049            final PathPermission[] pps = pi.pathPermissions;
7050            if (pps != null) {
7051                final String path = grantUri.uri.getPath();
7052                int i = pps.length;
7053                while (i > 0 && (!readMet || !writeMet)) {
7054                    i--;
7055                    PathPermission pp = pps[i];
7056                    if (pp.match(path)) {
7057                        if (!readMet) {
7058                            final String pprperm = pp.getReadPermission();
7059                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7060                                    + pprperm + " for " + pp.getPath()
7061                                    + ": match=" + pp.match(path)
7062                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7063                            if (pprperm != null) {
7064                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7065                                        == PERMISSION_GRANTED) {
7066                                    readMet = true;
7067                                } else {
7068                                    allowDefaultRead = false;
7069                                }
7070                            }
7071                        }
7072                        if (!writeMet) {
7073                            final String ppwperm = pp.getWritePermission();
7074                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7075                                    + ppwperm + " for " + pp.getPath()
7076                                    + ": match=" + pp.match(path)
7077                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7078                            if (ppwperm != null) {
7079                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7080                                        == PERMISSION_GRANTED) {
7081                                    writeMet = true;
7082                                } else {
7083                                    allowDefaultWrite = false;
7084                                }
7085                            }
7086                        }
7087                    }
7088                }
7089            }
7090
7091            // grant unprotected <provider> read/write, if not blocked by
7092            // <path-permission> above
7093            if (allowDefaultRead) readMet = true;
7094            if (allowDefaultWrite) writeMet = true;
7095
7096        } catch (RemoteException e) {
7097            return false;
7098        }
7099
7100        return readMet && writeMet;
7101    }
7102
7103    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7104        ProviderInfo pi = null;
7105        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7106        if (cpr != null) {
7107            pi = cpr.info;
7108        } else {
7109            try {
7110                pi = AppGlobals.getPackageManager().resolveContentProvider(
7111                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7112            } catch (RemoteException ex) {
7113            }
7114        }
7115        return pi;
7116    }
7117
7118    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7119        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7120        if (targetUris != null) {
7121            return targetUris.get(grantUri);
7122        }
7123        return null;
7124    }
7125
7126    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7127            String targetPkg, int targetUid, GrantUri grantUri) {
7128        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7129        if (targetUris == null) {
7130            targetUris = Maps.newArrayMap();
7131            mGrantedUriPermissions.put(targetUid, targetUris);
7132        }
7133
7134        UriPermission perm = targetUris.get(grantUri);
7135        if (perm == null) {
7136            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7137            targetUris.put(grantUri, perm);
7138        }
7139
7140        return perm;
7141    }
7142
7143    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7144            final int modeFlags) {
7145        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7146        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7147                : UriPermission.STRENGTH_OWNED;
7148
7149        // Root gets to do everything.
7150        if (uid == 0) {
7151            return true;
7152        }
7153
7154        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7155        if (perms == null) return false;
7156
7157        // First look for exact match
7158        final UriPermission exactPerm = perms.get(grantUri);
7159        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7160            return true;
7161        }
7162
7163        // No exact match, look for prefixes
7164        final int N = perms.size();
7165        for (int i = 0; i < N; i++) {
7166            final UriPermission perm = perms.valueAt(i);
7167            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7168                    && perm.getStrength(modeFlags) >= minStrength) {
7169                return true;
7170            }
7171        }
7172
7173        return false;
7174    }
7175
7176    /**
7177     * @param uri This uri must NOT contain an embedded userId.
7178     * @param userId The userId in which the uri is to be resolved.
7179     */
7180    @Override
7181    public int checkUriPermission(Uri uri, int pid, int uid,
7182            final int modeFlags, int userId) {
7183        enforceNotIsolatedCaller("checkUriPermission");
7184
7185        // Another redirected-binder-call permissions check as in
7186        // {@link checkComponentPermission}.
7187        Identity tlsIdentity = sCallerIdentity.get();
7188        if (tlsIdentity != null) {
7189            uid = tlsIdentity.uid;
7190            pid = tlsIdentity.pid;
7191        }
7192
7193        // Our own process gets to do everything.
7194        if (pid == MY_PID) {
7195            return PackageManager.PERMISSION_GRANTED;
7196        }
7197        synchronized (this) {
7198            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7199                    ? PackageManager.PERMISSION_GRANTED
7200                    : PackageManager.PERMISSION_DENIED;
7201        }
7202    }
7203
7204    /**
7205     * Check if the targetPkg can be granted permission to access uri by
7206     * the callingUid using the given modeFlags.  Throws a security exception
7207     * if callingUid is not allowed to do this.  Returns the uid of the target
7208     * if the URI permission grant should be performed; returns -1 if it is not
7209     * needed (for example targetPkg already has permission to access the URI).
7210     * If you already know the uid of the target, you can supply it in
7211     * lastTargetUid else set that to -1.
7212     */
7213    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7214            final int modeFlags, int lastTargetUid) {
7215        if (!Intent.isAccessUriMode(modeFlags)) {
7216            return -1;
7217        }
7218
7219        if (targetPkg != null) {
7220            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7221                    "Checking grant " + targetPkg + " permission to " + grantUri);
7222        }
7223
7224        final IPackageManager pm = AppGlobals.getPackageManager();
7225
7226        // If this is not a content: uri, we can't do anything with it.
7227        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7228            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7229                    "Can't grant URI permission for non-content URI: " + grantUri);
7230            return -1;
7231        }
7232
7233        final String authority = grantUri.uri.getAuthority();
7234        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7235        if (pi == null) {
7236            Slog.w(TAG, "No content provider found for permission check: " +
7237                    grantUri.uri.toSafeString());
7238            return -1;
7239        }
7240
7241        int targetUid = lastTargetUid;
7242        if (targetUid < 0 && targetPkg != null) {
7243            try {
7244                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7245                if (targetUid < 0) {
7246                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7247                            "Can't grant URI permission no uid for: " + targetPkg);
7248                    return -1;
7249                }
7250            } catch (RemoteException ex) {
7251                return -1;
7252            }
7253        }
7254
7255        if (targetUid >= 0) {
7256            // First...  does the target actually need this permission?
7257            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7258                // No need to grant the target this permission.
7259                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7260                        "Target " + targetPkg + " already has full permission to " + grantUri);
7261                return -1;
7262            }
7263        } else {
7264            // First...  there is no target package, so can anyone access it?
7265            boolean allowed = pi.exported;
7266            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7267                if (pi.readPermission != null) {
7268                    allowed = false;
7269                }
7270            }
7271            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7272                if (pi.writePermission != null) {
7273                    allowed = false;
7274                }
7275            }
7276            if (allowed) {
7277                return -1;
7278            }
7279        }
7280
7281        /* There is a special cross user grant if:
7282         * - The target is on another user.
7283         * - Apps on the current user can access the uri without any uid permissions.
7284         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7285         * grant uri permissions.
7286         */
7287        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7288                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7289                modeFlags, false /*without considering the uid permissions*/);
7290
7291        // Second...  is the provider allowing granting of URI permissions?
7292        if (!specialCrossUserGrant) {
7293            if (!pi.grantUriPermissions) {
7294                throw new SecurityException("Provider " + pi.packageName
7295                        + "/" + pi.name
7296                        + " does not allow granting of Uri permissions (uri "
7297                        + grantUri + ")");
7298            }
7299            if (pi.uriPermissionPatterns != null) {
7300                final int N = pi.uriPermissionPatterns.length;
7301                boolean allowed = false;
7302                for (int i=0; i<N; i++) {
7303                    if (pi.uriPermissionPatterns[i] != null
7304                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7305                        allowed = true;
7306                        break;
7307                    }
7308                }
7309                if (!allowed) {
7310                    throw new SecurityException("Provider " + pi.packageName
7311                            + "/" + pi.name
7312                            + " does not allow granting of permission to path of Uri "
7313                            + grantUri);
7314                }
7315            }
7316        }
7317
7318        // Third...  does the caller itself have permission to access
7319        // this uri?
7320        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7321            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7322                // Require they hold a strong enough Uri permission
7323                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7324                    throw new SecurityException("Uid " + callingUid
7325                            + " does not have permission to uri " + grantUri);
7326                }
7327            }
7328        }
7329        return targetUid;
7330    }
7331
7332    /**
7333     * @param uri This uri must NOT contain an embedded userId.
7334     * @param userId The userId in which the uri is to be resolved.
7335     */
7336    @Override
7337    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7338            final int modeFlags, int userId) {
7339        enforceNotIsolatedCaller("checkGrantUriPermission");
7340        synchronized(this) {
7341            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7342                    new GrantUri(userId, uri, false), modeFlags, -1);
7343        }
7344    }
7345
7346    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7347            final int modeFlags, UriPermissionOwner owner) {
7348        if (!Intent.isAccessUriMode(modeFlags)) {
7349            return;
7350        }
7351
7352        // So here we are: the caller has the assumed permission
7353        // to the uri, and the target doesn't.  Let's now give this to
7354        // the target.
7355
7356        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7357                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7358
7359        final String authority = grantUri.uri.getAuthority();
7360        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7361        if (pi == null) {
7362            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7363            return;
7364        }
7365
7366        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7367            grantUri.prefix = true;
7368        }
7369        final UriPermission perm = findOrCreateUriPermissionLocked(
7370                pi.packageName, targetPkg, targetUid, grantUri);
7371        perm.grantModes(modeFlags, owner);
7372    }
7373
7374    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7375            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7376        if (targetPkg == null) {
7377            throw new NullPointerException("targetPkg");
7378        }
7379        int targetUid;
7380        final IPackageManager pm = AppGlobals.getPackageManager();
7381        try {
7382            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7383        } catch (RemoteException ex) {
7384            return;
7385        }
7386
7387        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7388                targetUid);
7389        if (targetUid < 0) {
7390            return;
7391        }
7392
7393        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7394                owner);
7395    }
7396
7397    static class NeededUriGrants extends ArrayList<GrantUri> {
7398        final String targetPkg;
7399        final int targetUid;
7400        final int flags;
7401
7402        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7403            this.targetPkg = targetPkg;
7404            this.targetUid = targetUid;
7405            this.flags = flags;
7406        }
7407    }
7408
7409    /**
7410     * Like checkGrantUriPermissionLocked, but takes an Intent.
7411     */
7412    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7413            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7414        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7415                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7416                + " clip=" + (intent != null ? intent.getClipData() : null)
7417                + " from " + intent + "; flags=0x"
7418                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7419
7420        if (targetPkg == null) {
7421            throw new NullPointerException("targetPkg");
7422        }
7423
7424        if (intent == null) {
7425            return null;
7426        }
7427        Uri data = intent.getData();
7428        ClipData clip = intent.getClipData();
7429        if (data == null && clip == null) {
7430            return null;
7431        }
7432        // Default userId for uris in the intent (if they don't specify it themselves)
7433        int contentUserHint = intent.getContentUserHint();
7434        if (contentUserHint == UserHandle.USER_CURRENT) {
7435            contentUserHint = UserHandle.getUserId(callingUid);
7436        }
7437        final IPackageManager pm = AppGlobals.getPackageManager();
7438        int targetUid;
7439        if (needed != null) {
7440            targetUid = needed.targetUid;
7441        } else {
7442            try {
7443                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7444            } catch (RemoteException ex) {
7445                return null;
7446            }
7447            if (targetUid < 0) {
7448                if (DEBUG_URI_PERMISSION) {
7449                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7450                            + " on user " + targetUserId);
7451                }
7452                return null;
7453            }
7454        }
7455        if (data != null) {
7456            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7457            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7458                    targetUid);
7459            if (targetUid > 0) {
7460                if (needed == null) {
7461                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7462                }
7463                needed.add(grantUri);
7464            }
7465        }
7466        if (clip != null) {
7467            for (int i=0; i<clip.getItemCount(); i++) {
7468                Uri uri = clip.getItemAt(i).getUri();
7469                if (uri != null) {
7470                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7471                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7472                            targetUid);
7473                    if (targetUid > 0) {
7474                        if (needed == null) {
7475                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7476                        }
7477                        needed.add(grantUri);
7478                    }
7479                } else {
7480                    Intent clipIntent = clip.getItemAt(i).getIntent();
7481                    if (clipIntent != null) {
7482                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7483                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7484                        if (newNeeded != null) {
7485                            needed = newNeeded;
7486                        }
7487                    }
7488                }
7489            }
7490        }
7491
7492        return needed;
7493    }
7494
7495    /**
7496     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7497     */
7498    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7499            UriPermissionOwner owner) {
7500        if (needed != null) {
7501            for (int i=0; i<needed.size(); i++) {
7502                GrantUri grantUri = needed.get(i);
7503                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7504                        grantUri, needed.flags, owner);
7505            }
7506        }
7507    }
7508
7509    void grantUriPermissionFromIntentLocked(int callingUid,
7510            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7511        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7512                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7513        if (needed == null) {
7514            return;
7515        }
7516
7517        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7518    }
7519
7520    /**
7521     * @param uri This uri must NOT contain an embedded userId.
7522     * @param userId The userId in which the uri is to be resolved.
7523     */
7524    @Override
7525    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7526            final int modeFlags, int userId) {
7527        enforceNotIsolatedCaller("grantUriPermission");
7528        GrantUri grantUri = new GrantUri(userId, uri, false);
7529        synchronized(this) {
7530            final ProcessRecord r = getRecordForAppLocked(caller);
7531            if (r == null) {
7532                throw new SecurityException("Unable to find app for caller "
7533                        + caller
7534                        + " when granting permission to uri " + grantUri);
7535            }
7536            if (targetPkg == null) {
7537                throw new IllegalArgumentException("null target");
7538            }
7539            if (grantUri == null) {
7540                throw new IllegalArgumentException("null uri");
7541            }
7542
7543            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7544                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7545                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7546                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7547
7548            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7549                    UserHandle.getUserId(r.uid));
7550        }
7551    }
7552
7553    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7554        if (perm.modeFlags == 0) {
7555            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7556                    perm.targetUid);
7557            if (perms != null) {
7558                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7559                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7560
7561                perms.remove(perm.uri);
7562                if (perms.isEmpty()) {
7563                    mGrantedUriPermissions.remove(perm.targetUid);
7564                }
7565            }
7566        }
7567    }
7568
7569    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7570        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7571
7572        final IPackageManager pm = AppGlobals.getPackageManager();
7573        final String authority = grantUri.uri.getAuthority();
7574        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7575        if (pi == null) {
7576            Slog.w(TAG, "No content provider found for permission revoke: "
7577                    + grantUri.toSafeString());
7578            return;
7579        }
7580
7581        // Does the caller have this permission on the URI?
7582        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7583            // If they don't have direct access to the URI, then revoke any
7584            // ownerless URI permissions that have been granted to them.
7585            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7586            if (perms != null) {
7587                boolean persistChanged = false;
7588                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7589                    final UriPermission perm = it.next();
7590                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7591                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7592                        if (DEBUG_URI_PERMISSION)
7593                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7594                                    " permission to " + perm.uri);
7595                        persistChanged |= perm.revokeModes(
7596                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7597                        if (perm.modeFlags == 0) {
7598                            it.remove();
7599                        }
7600                    }
7601                }
7602                if (perms.isEmpty()) {
7603                    mGrantedUriPermissions.remove(callingUid);
7604                }
7605                if (persistChanged) {
7606                    schedulePersistUriGrants();
7607                }
7608            }
7609            return;
7610        }
7611
7612        boolean persistChanged = false;
7613
7614        // Go through all of the permissions and remove any that match.
7615        int N = mGrantedUriPermissions.size();
7616        for (int i = 0; i < N; i++) {
7617            final int targetUid = mGrantedUriPermissions.keyAt(i);
7618            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7619
7620            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7621                final UriPermission perm = it.next();
7622                if (perm.uri.sourceUserId == grantUri.sourceUserId
7623                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7624                    if (DEBUG_URI_PERMISSION)
7625                        Slog.v(TAG,
7626                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7627                    persistChanged |= perm.revokeModes(
7628                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7629                    if (perm.modeFlags == 0) {
7630                        it.remove();
7631                    }
7632                }
7633            }
7634
7635            if (perms.isEmpty()) {
7636                mGrantedUriPermissions.remove(targetUid);
7637                N--;
7638                i--;
7639            }
7640        }
7641
7642        if (persistChanged) {
7643            schedulePersistUriGrants();
7644        }
7645    }
7646
7647    /**
7648     * @param uri This uri must NOT contain an embedded userId.
7649     * @param userId The userId in which the uri is to be resolved.
7650     */
7651    @Override
7652    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7653            int userId) {
7654        enforceNotIsolatedCaller("revokeUriPermission");
7655        synchronized(this) {
7656            final ProcessRecord r = getRecordForAppLocked(caller);
7657            if (r == null) {
7658                throw new SecurityException("Unable to find app for caller "
7659                        + caller
7660                        + " when revoking permission to uri " + uri);
7661            }
7662            if (uri == null) {
7663                Slog.w(TAG, "revokeUriPermission: null uri");
7664                return;
7665            }
7666
7667            if (!Intent.isAccessUriMode(modeFlags)) {
7668                return;
7669            }
7670
7671            final IPackageManager pm = AppGlobals.getPackageManager();
7672            final String authority = uri.getAuthority();
7673            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7674            if (pi == null) {
7675                Slog.w(TAG, "No content provider found for permission revoke: "
7676                        + uri.toSafeString());
7677                return;
7678            }
7679
7680            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7681        }
7682    }
7683
7684    /**
7685     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7686     * given package.
7687     *
7688     * @param packageName Package name to match, or {@code null} to apply to all
7689     *            packages.
7690     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7691     *            to all users.
7692     * @param persistable If persistable grants should be removed.
7693     */
7694    private void removeUriPermissionsForPackageLocked(
7695            String packageName, int userHandle, boolean persistable) {
7696        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7697            throw new IllegalArgumentException("Must narrow by either package or user");
7698        }
7699
7700        boolean persistChanged = false;
7701
7702        int N = mGrantedUriPermissions.size();
7703        for (int i = 0; i < N; i++) {
7704            final int targetUid = mGrantedUriPermissions.keyAt(i);
7705            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7706
7707            // Only inspect grants matching user
7708            if (userHandle == UserHandle.USER_ALL
7709                    || userHandle == UserHandle.getUserId(targetUid)) {
7710                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7711                    final UriPermission perm = it.next();
7712
7713                    // Only inspect grants matching package
7714                    if (packageName == null || perm.sourcePkg.equals(packageName)
7715                            || perm.targetPkg.equals(packageName)) {
7716                        persistChanged |= perm.revokeModes(persistable
7717                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7718
7719                        // Only remove when no modes remain; any persisted grants
7720                        // will keep this alive.
7721                        if (perm.modeFlags == 0) {
7722                            it.remove();
7723                        }
7724                    }
7725                }
7726
7727                if (perms.isEmpty()) {
7728                    mGrantedUriPermissions.remove(targetUid);
7729                    N--;
7730                    i--;
7731                }
7732            }
7733        }
7734
7735        if (persistChanged) {
7736            schedulePersistUriGrants();
7737        }
7738    }
7739
7740    @Override
7741    public IBinder newUriPermissionOwner(String name) {
7742        enforceNotIsolatedCaller("newUriPermissionOwner");
7743        synchronized(this) {
7744            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7745            return owner.getExternalTokenLocked();
7746        }
7747    }
7748
7749    /**
7750     * @param uri This uri must NOT contain an embedded userId.
7751     * @param sourceUserId The userId in which the uri is to be resolved.
7752     * @param targetUserId The userId of the app that receives the grant.
7753     */
7754    @Override
7755    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7756            final int modeFlags, int sourceUserId, int targetUserId) {
7757        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7758                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7759        synchronized(this) {
7760            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7761            if (owner == null) {
7762                throw new IllegalArgumentException("Unknown owner: " + token);
7763            }
7764            if (fromUid != Binder.getCallingUid()) {
7765                if (Binder.getCallingUid() != Process.myUid()) {
7766                    // Only system code can grant URI permissions on behalf
7767                    // of other users.
7768                    throw new SecurityException("nice try");
7769                }
7770            }
7771            if (targetPkg == null) {
7772                throw new IllegalArgumentException("null target");
7773            }
7774            if (uri == null) {
7775                throw new IllegalArgumentException("null uri");
7776            }
7777
7778            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7779                    modeFlags, owner, targetUserId);
7780        }
7781    }
7782
7783    /**
7784     * @param uri This uri must NOT contain an embedded userId.
7785     * @param userId The userId in which the uri is to be resolved.
7786     */
7787    @Override
7788    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7789        synchronized(this) {
7790            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7791            if (owner == null) {
7792                throw new IllegalArgumentException("Unknown owner: " + token);
7793            }
7794
7795            if (uri == null) {
7796                owner.removeUriPermissionsLocked(mode);
7797            } else {
7798                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7799            }
7800        }
7801    }
7802
7803    private void schedulePersistUriGrants() {
7804        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7805            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7806                    10 * DateUtils.SECOND_IN_MILLIS);
7807        }
7808    }
7809
7810    private void writeGrantedUriPermissions() {
7811        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7812
7813        // Snapshot permissions so we can persist without lock
7814        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7815        synchronized (this) {
7816            final int size = mGrantedUriPermissions.size();
7817            for (int i = 0; i < size; i++) {
7818                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7819                for (UriPermission perm : perms.values()) {
7820                    if (perm.persistedModeFlags != 0) {
7821                        persist.add(perm.snapshot());
7822                    }
7823                }
7824            }
7825        }
7826
7827        FileOutputStream fos = null;
7828        try {
7829            fos = mGrantFile.startWrite();
7830
7831            XmlSerializer out = new FastXmlSerializer();
7832            out.setOutput(fos, "utf-8");
7833            out.startDocument(null, true);
7834            out.startTag(null, TAG_URI_GRANTS);
7835            for (UriPermission.Snapshot perm : persist) {
7836                out.startTag(null, TAG_URI_GRANT);
7837                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7838                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7839                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7840                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7841                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7842                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7843                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7844                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7845                out.endTag(null, TAG_URI_GRANT);
7846            }
7847            out.endTag(null, TAG_URI_GRANTS);
7848            out.endDocument();
7849
7850            mGrantFile.finishWrite(fos);
7851        } catch (IOException e) {
7852            if (fos != null) {
7853                mGrantFile.failWrite(fos);
7854            }
7855        }
7856    }
7857
7858    private void readGrantedUriPermissionsLocked() {
7859        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7860
7861        final long now = System.currentTimeMillis();
7862
7863        FileInputStream fis = null;
7864        try {
7865            fis = mGrantFile.openRead();
7866            final XmlPullParser in = Xml.newPullParser();
7867            in.setInput(fis, null);
7868
7869            int type;
7870            while ((type = in.next()) != END_DOCUMENT) {
7871                final String tag = in.getName();
7872                if (type == START_TAG) {
7873                    if (TAG_URI_GRANT.equals(tag)) {
7874                        final int sourceUserId;
7875                        final int targetUserId;
7876                        final int userHandle = readIntAttribute(in,
7877                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7878                        if (userHandle != UserHandle.USER_NULL) {
7879                            // For backwards compatibility.
7880                            sourceUserId = userHandle;
7881                            targetUserId = userHandle;
7882                        } else {
7883                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7884                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7885                        }
7886                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7887                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7888                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7889                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7890                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7891                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7892
7893                        // Sanity check that provider still belongs to source package
7894                        final ProviderInfo pi = getProviderInfoLocked(
7895                                uri.getAuthority(), sourceUserId);
7896                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7897                            int targetUid = -1;
7898                            try {
7899                                targetUid = AppGlobals.getPackageManager()
7900                                        .getPackageUid(targetPkg, targetUserId);
7901                            } catch (RemoteException e) {
7902                            }
7903                            if (targetUid != -1) {
7904                                final UriPermission perm = findOrCreateUriPermissionLocked(
7905                                        sourcePkg, targetPkg, targetUid,
7906                                        new GrantUri(sourceUserId, uri, prefix));
7907                                perm.initPersistedModes(modeFlags, createdTime);
7908                            }
7909                        } else {
7910                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7911                                    + " but instead found " + pi);
7912                        }
7913                    }
7914                }
7915            }
7916        } catch (FileNotFoundException e) {
7917            // Missing grants is okay
7918        } catch (IOException e) {
7919            Log.wtf(TAG, "Failed reading Uri grants", e);
7920        } catch (XmlPullParserException e) {
7921            Log.wtf(TAG, "Failed reading Uri grants", e);
7922        } finally {
7923            IoUtils.closeQuietly(fis);
7924        }
7925    }
7926
7927    /**
7928     * @param uri This uri must NOT contain an embedded userId.
7929     * @param userId The userId in which the uri is to be resolved.
7930     */
7931    @Override
7932    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7933        enforceNotIsolatedCaller("takePersistableUriPermission");
7934
7935        Preconditions.checkFlagsArgument(modeFlags,
7936                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7937
7938        synchronized (this) {
7939            final int callingUid = Binder.getCallingUid();
7940            boolean persistChanged = false;
7941            GrantUri grantUri = new GrantUri(userId, uri, false);
7942
7943            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7944                    new GrantUri(userId, uri, false));
7945            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7946                    new GrantUri(userId, uri, true));
7947
7948            final boolean exactValid = (exactPerm != null)
7949                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7950            final boolean prefixValid = (prefixPerm != null)
7951                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7952
7953            if (!(exactValid || prefixValid)) {
7954                throw new SecurityException("No persistable permission grants found for UID "
7955                        + callingUid + " and Uri " + grantUri.toSafeString());
7956            }
7957
7958            if (exactValid) {
7959                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7960            }
7961            if (prefixValid) {
7962                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7963            }
7964
7965            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7966
7967            if (persistChanged) {
7968                schedulePersistUriGrants();
7969            }
7970        }
7971    }
7972
7973    /**
7974     * @param uri This uri must NOT contain an embedded userId.
7975     * @param userId The userId in which the uri is to be resolved.
7976     */
7977    @Override
7978    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7979        enforceNotIsolatedCaller("releasePersistableUriPermission");
7980
7981        Preconditions.checkFlagsArgument(modeFlags,
7982                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7983
7984        synchronized (this) {
7985            final int callingUid = Binder.getCallingUid();
7986            boolean persistChanged = false;
7987
7988            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7989                    new GrantUri(userId, uri, false));
7990            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7991                    new GrantUri(userId, uri, true));
7992            if (exactPerm == null && prefixPerm == null) {
7993                throw new SecurityException("No permission grants found for UID " + callingUid
7994                        + " and Uri " + uri.toSafeString());
7995            }
7996
7997            if (exactPerm != null) {
7998                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7999                removeUriPermissionIfNeededLocked(exactPerm);
8000            }
8001            if (prefixPerm != null) {
8002                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8003                removeUriPermissionIfNeededLocked(prefixPerm);
8004            }
8005
8006            if (persistChanged) {
8007                schedulePersistUriGrants();
8008            }
8009        }
8010    }
8011
8012    /**
8013     * Prune any older {@link UriPermission} for the given UID until outstanding
8014     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8015     *
8016     * @return if any mutations occured that require persisting.
8017     */
8018    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8019        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8020        if (perms == null) return false;
8021        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8022
8023        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8024        for (UriPermission perm : perms.values()) {
8025            if (perm.persistedModeFlags != 0) {
8026                persisted.add(perm);
8027            }
8028        }
8029
8030        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8031        if (trimCount <= 0) return false;
8032
8033        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8034        for (int i = 0; i < trimCount; i++) {
8035            final UriPermission perm = persisted.get(i);
8036
8037            if (DEBUG_URI_PERMISSION) {
8038                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8039            }
8040
8041            perm.releasePersistableModes(~0);
8042            removeUriPermissionIfNeededLocked(perm);
8043        }
8044
8045        return true;
8046    }
8047
8048    @Override
8049    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8050            String packageName, boolean incoming) {
8051        enforceNotIsolatedCaller("getPersistedUriPermissions");
8052        Preconditions.checkNotNull(packageName, "packageName");
8053
8054        final int callingUid = Binder.getCallingUid();
8055        final IPackageManager pm = AppGlobals.getPackageManager();
8056        try {
8057            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8058            if (packageUid != callingUid) {
8059                throw new SecurityException(
8060                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8061            }
8062        } catch (RemoteException e) {
8063            throw new SecurityException("Failed to verify package name ownership");
8064        }
8065
8066        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8067        synchronized (this) {
8068            if (incoming) {
8069                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8070                        callingUid);
8071                if (perms == null) {
8072                    Slog.w(TAG, "No permission grants found for " + packageName);
8073                } else {
8074                    for (UriPermission perm : perms.values()) {
8075                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8076                            result.add(perm.buildPersistedPublicApiObject());
8077                        }
8078                    }
8079                }
8080            } else {
8081                final int size = mGrantedUriPermissions.size();
8082                for (int i = 0; i < size; i++) {
8083                    final ArrayMap<GrantUri, UriPermission> perms =
8084                            mGrantedUriPermissions.valueAt(i);
8085                    for (UriPermission perm : perms.values()) {
8086                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8087                            result.add(perm.buildPersistedPublicApiObject());
8088                        }
8089                    }
8090                }
8091            }
8092        }
8093        return new ParceledListSlice<android.content.UriPermission>(result);
8094    }
8095
8096    @Override
8097    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8098        synchronized (this) {
8099            ProcessRecord app =
8100                who != null ? getRecordForAppLocked(who) : null;
8101            if (app == null) return;
8102
8103            Message msg = Message.obtain();
8104            msg.what = WAIT_FOR_DEBUGGER_MSG;
8105            msg.obj = app;
8106            msg.arg1 = waiting ? 1 : 0;
8107            mHandler.sendMessage(msg);
8108        }
8109    }
8110
8111    @Override
8112    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8113        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8114        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8115        outInfo.availMem = Process.getFreeMemory();
8116        outInfo.totalMem = Process.getTotalMemory();
8117        outInfo.threshold = homeAppMem;
8118        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8119        outInfo.hiddenAppThreshold = cachedAppMem;
8120        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8121                ProcessList.SERVICE_ADJ);
8122        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8123                ProcessList.VISIBLE_APP_ADJ);
8124        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8125                ProcessList.FOREGROUND_APP_ADJ);
8126    }
8127
8128    // =========================================================
8129    // TASK MANAGEMENT
8130    // =========================================================
8131
8132    @Override
8133    public List<IAppTask> getAppTasks(String callingPackage) {
8134        int callingUid = Binder.getCallingUid();
8135        long ident = Binder.clearCallingIdentity();
8136
8137        synchronized(this) {
8138            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8139            try {
8140                if (localLOGV) Slog.v(TAG, "getAppTasks");
8141
8142                final int N = mRecentTasks.size();
8143                for (int i = 0; i < N; i++) {
8144                    TaskRecord tr = mRecentTasks.get(i);
8145                    // Skip tasks that do not match the caller.  We don't need to verify
8146                    // callingPackage, because we are also limiting to callingUid and know
8147                    // that will limit to the correct security sandbox.
8148                    if (tr.effectiveUid != callingUid) {
8149                        continue;
8150                    }
8151                    Intent intent = tr.getBaseIntent();
8152                    if (intent == null ||
8153                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8154                        continue;
8155                    }
8156                    ActivityManager.RecentTaskInfo taskInfo =
8157                            createRecentTaskInfoFromTaskRecord(tr);
8158                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8159                    list.add(taskImpl);
8160                }
8161            } finally {
8162                Binder.restoreCallingIdentity(ident);
8163            }
8164            return list;
8165        }
8166    }
8167
8168    @Override
8169    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8170        final int callingUid = Binder.getCallingUid();
8171        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8172
8173        synchronized(this) {
8174            if (localLOGV) Slog.v(
8175                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8176
8177            final boolean allowed = checkCallingPermission(
8178                    android.Manifest.permission.GET_TASKS)
8179                    == PackageManager.PERMISSION_GRANTED;
8180            if (!allowed) {
8181                Slog.w(TAG, "getTasks: caller " + callingUid
8182                        + " does not hold GET_TASKS; limiting output");
8183            }
8184
8185            // TODO: Improve with MRU list from all ActivityStacks.
8186            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8187        }
8188
8189        return list;
8190    }
8191
8192    TaskRecord getMostRecentTask() {
8193        return mRecentTasks.get(0);
8194    }
8195
8196    /**
8197     * Creates a new RecentTaskInfo from a TaskRecord.
8198     */
8199    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8200        // Update the task description to reflect any changes in the task stack
8201        tr.updateTaskDescription();
8202
8203        // Compose the recent task info
8204        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8205        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8206        rti.persistentId = tr.taskId;
8207        rti.baseIntent = new Intent(tr.getBaseIntent());
8208        rti.origActivity = tr.origActivity;
8209        rti.description = tr.lastDescription;
8210        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8211        rti.userId = tr.userId;
8212        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8213        rti.firstActiveTime = tr.firstActiveTime;
8214        rti.lastActiveTime = tr.lastActiveTime;
8215        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8216        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8217        return rti;
8218    }
8219
8220    @Override
8221    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8222        final int callingUid = Binder.getCallingUid();
8223        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8224                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8225
8226        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8227        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8228        synchronized (this) {
8229            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8230                    == PackageManager.PERMISSION_GRANTED;
8231            if (!allowed) {
8232                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8233                        + " does not hold GET_TASKS; limiting output");
8234            }
8235            final boolean detailed = checkCallingPermission(
8236                    android.Manifest.permission.GET_DETAILED_TASKS)
8237                    == PackageManager.PERMISSION_GRANTED;
8238
8239            final int N = mRecentTasks.size();
8240            ArrayList<ActivityManager.RecentTaskInfo> res
8241                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8242                            maxNum < N ? maxNum : N);
8243
8244            final Set<Integer> includedUsers;
8245            if (includeProfiles) {
8246                includedUsers = getProfileIdsLocked(userId);
8247            } else {
8248                includedUsers = new HashSet<Integer>();
8249            }
8250            includedUsers.add(Integer.valueOf(userId));
8251
8252            for (int i=0; i<N && maxNum > 0; i++) {
8253                TaskRecord tr = mRecentTasks.get(i);
8254                // Only add calling user or related users recent tasks
8255                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8256                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8257                    continue;
8258                }
8259
8260                // Return the entry if desired by the caller.  We always return
8261                // the first entry, because callers always expect this to be the
8262                // foreground app.  We may filter others if the caller has
8263                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8264                // we should exclude the entry.
8265
8266                if (i == 0
8267                        || withExcluded
8268                        || (tr.intent == null)
8269                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8270                                == 0)) {
8271                    if (!allowed) {
8272                        // If the caller doesn't have the GET_TASKS permission, then only
8273                        // allow them to see a small subset of tasks -- their own and home.
8274                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8275                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8276                            continue;
8277                        }
8278                    }
8279                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8280                        if (tr.stack != null && tr.stack.isHomeStack()) {
8281                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8282                            continue;
8283                        }
8284                    }
8285                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8286                        // Don't include auto remove tasks that are finished or finishing.
8287                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8288                                + tr);
8289                        continue;
8290                    }
8291                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8292                            && !tr.isAvailable) {
8293                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8294                        continue;
8295                    }
8296
8297                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8298                    if (!detailed) {
8299                        rti.baseIntent.replaceExtras((Bundle)null);
8300                    }
8301
8302                    res.add(rti);
8303                    maxNum--;
8304                }
8305            }
8306            return res;
8307        }
8308    }
8309
8310    private TaskRecord recentTaskForIdLocked(int id) {
8311        final int N = mRecentTasks.size();
8312            for (int i=0; i<N; i++) {
8313                TaskRecord tr = mRecentTasks.get(i);
8314                if (tr.taskId == id) {
8315                    return tr;
8316                }
8317            }
8318            return null;
8319    }
8320
8321    @Override
8322    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8323        synchronized (this) {
8324            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8325                    "getTaskThumbnail()");
8326            TaskRecord tr = recentTaskForIdLocked(id);
8327            if (tr != null) {
8328                return tr.getTaskThumbnailLocked();
8329            }
8330        }
8331        return null;
8332    }
8333
8334    @Override
8335    public int addAppTask(IBinder activityToken, Intent intent,
8336            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8337        final int callingUid = Binder.getCallingUid();
8338        final long callingIdent = Binder.clearCallingIdentity();
8339
8340        try {
8341            synchronized (this) {
8342                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8343                if (r == null) {
8344                    throw new IllegalArgumentException("Activity does not exist; token="
8345                            + activityToken);
8346                }
8347                ComponentName comp = intent.getComponent();
8348                if (comp == null) {
8349                    throw new IllegalArgumentException("Intent " + intent
8350                            + " must specify explicit component");
8351                }
8352                if (thumbnail.getWidth() != mThumbnailWidth
8353                        || thumbnail.getHeight() != mThumbnailHeight) {
8354                    throw new IllegalArgumentException("Bad thumbnail size: got "
8355                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8356                            + mThumbnailWidth + "x" + mThumbnailHeight);
8357                }
8358                if (intent.getSelector() != null) {
8359                    intent.setSelector(null);
8360                }
8361                if (intent.getSourceBounds() != null) {
8362                    intent.setSourceBounds(null);
8363                }
8364                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8365                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8366                        // The caller has added this as an auto-remove task...  that makes no
8367                        // sense, so turn off auto-remove.
8368                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8369                    }
8370                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8371                    // Must be a new task.
8372                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8373                }
8374                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8375                    mLastAddedTaskActivity = null;
8376                }
8377                ActivityInfo ainfo = mLastAddedTaskActivity;
8378                if (ainfo == null) {
8379                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8380                            comp, 0, UserHandle.getUserId(callingUid));
8381                    if (ainfo.applicationInfo.uid != callingUid) {
8382                        throw new SecurityException(
8383                                "Can't add task for another application: target uid="
8384                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8385                    }
8386                }
8387
8388                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8389                        intent, description);
8390
8391                int trimIdx = trimRecentsForTask(task, false);
8392                if (trimIdx >= 0) {
8393                    // If this would have caused a trim, then we'll abort because that
8394                    // means it would be added at the end of the list but then just removed.
8395                    return -1;
8396                }
8397
8398                final int N = mRecentTasks.size();
8399                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8400                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8401                    tr.removedFromRecents(mTaskPersister);
8402                }
8403
8404                task.inRecents = true;
8405                mRecentTasks.add(task);
8406                r.task.stack.addTask(task, false, false);
8407
8408                task.setLastThumbnail(thumbnail);
8409                task.freeLastThumbnail();
8410
8411                return task.taskId;
8412            }
8413        } finally {
8414            Binder.restoreCallingIdentity(callingIdent);
8415        }
8416    }
8417
8418    @Override
8419    public Point getAppTaskThumbnailSize() {
8420        synchronized (this) {
8421            return new Point(mThumbnailWidth,  mThumbnailHeight);
8422        }
8423    }
8424
8425    @Override
8426    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8427        synchronized (this) {
8428            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8429            if (r != null) {
8430                r.setTaskDescription(td);
8431                r.task.updateTaskDescription();
8432            }
8433        }
8434    }
8435
8436    @Override
8437    public Bitmap getTaskDescriptionIcon(String filename) {
8438        if (!FileUtils.isValidExtFilename(filename)
8439                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8440            throw new IllegalArgumentException("Bad filename: " + filename);
8441        }
8442        return mTaskPersister.getTaskDescriptionIcon(filename);
8443    }
8444
8445    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8446        mRecentTasks.remove(tr);
8447        tr.removedFromRecents(mTaskPersister);
8448        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8449        Intent baseIntent = new Intent(
8450                tr.intent != null ? tr.intent : tr.affinityIntent);
8451        ComponentName component = baseIntent.getComponent();
8452        if (component == null) {
8453            Slog.w(TAG, "Now component for base intent of task: " + tr);
8454            return;
8455        }
8456
8457        // Find any running services associated with this app.
8458        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8459
8460        if (killProcesses) {
8461            // Find any running processes associated with this app.
8462            final String pkg = component.getPackageName();
8463            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8464            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8465            for (int i=0; i<pmap.size(); i++) {
8466                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8467                for (int j=0; j<uids.size(); j++) {
8468                    ProcessRecord proc = uids.valueAt(j);
8469                    if (proc.userId != tr.userId) {
8470                        continue;
8471                    }
8472                    if (!proc.pkgList.containsKey(pkg)) {
8473                        continue;
8474                    }
8475                    procs.add(proc);
8476                }
8477            }
8478
8479            // Kill the running processes.
8480            for (int i=0; i<procs.size(); i++) {
8481                ProcessRecord pr = procs.get(i);
8482                if (pr == mHomeProcess) {
8483                    // Don't kill the home process along with tasks from the same package.
8484                    continue;
8485                }
8486                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8487                    pr.kill("remove task", true);
8488                } else {
8489                    pr.waitingToKill = "remove task";
8490                }
8491            }
8492        }
8493    }
8494
8495    /**
8496     * Removes the task with the specified task id.
8497     *
8498     * @param taskId Identifier of the task to be removed.
8499     * @param flags Additional operational flags.  May be 0 or
8500     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8501     * @return Returns true if the given task was found and removed.
8502     */
8503    private boolean removeTaskByIdLocked(int taskId, int flags) {
8504        TaskRecord tr = recentTaskForIdLocked(taskId);
8505        if (tr != null) {
8506            tr.removeTaskActivitiesLocked();
8507            cleanUpRemovedTaskLocked(tr, flags);
8508            if (tr.isPersistable) {
8509                notifyTaskPersisterLocked(null, true);
8510            }
8511            return true;
8512        }
8513        return false;
8514    }
8515
8516    @Override
8517    public boolean removeTask(int taskId, int flags) {
8518        synchronized (this) {
8519            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8520                    "removeTask()");
8521            long ident = Binder.clearCallingIdentity();
8522            try {
8523                return removeTaskByIdLocked(taskId, flags);
8524            } finally {
8525                Binder.restoreCallingIdentity(ident);
8526            }
8527        }
8528    }
8529
8530    /**
8531     * TODO: Add mController hook
8532     */
8533    @Override
8534    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8535        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8536                "moveTaskToFront()");
8537
8538        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8539        synchronized(this) {
8540            moveTaskToFrontLocked(taskId, flags, options);
8541        }
8542    }
8543
8544    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8545        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8546                Binder.getCallingUid(), -1, -1, "Task to front")) {
8547            ActivityOptions.abort(options);
8548            return;
8549        }
8550        final long origId = Binder.clearCallingIdentity();
8551        try {
8552            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8553            if (task == null) {
8554                return;
8555            }
8556            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8557                mStackSupervisor.showLockTaskToast();
8558                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8559                return;
8560            }
8561            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8562            if (prev != null && prev.isRecentsActivity()) {
8563                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8564            }
8565            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8566        } finally {
8567            Binder.restoreCallingIdentity(origId);
8568        }
8569        ActivityOptions.abort(options);
8570    }
8571
8572    @Override
8573    public void moveTaskToBack(int taskId) {
8574        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8575                "moveTaskToBack()");
8576
8577        synchronized(this) {
8578            TaskRecord tr = recentTaskForIdLocked(taskId);
8579            if (tr != null) {
8580                if (tr == mStackSupervisor.mLockTaskModeTask) {
8581                    mStackSupervisor.showLockTaskToast();
8582                    return;
8583                }
8584                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8585                ActivityStack stack = tr.stack;
8586                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8587                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8588                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8589                        return;
8590                    }
8591                }
8592                final long origId = Binder.clearCallingIdentity();
8593                try {
8594                    stack.moveTaskToBackLocked(taskId, null);
8595                } finally {
8596                    Binder.restoreCallingIdentity(origId);
8597                }
8598            }
8599        }
8600    }
8601
8602    /**
8603     * Moves an activity, and all of the other activities within the same task, to the bottom
8604     * of the history stack.  The activity's order within the task is unchanged.
8605     *
8606     * @param token A reference to the activity we wish to move
8607     * @param nonRoot If false then this only works if the activity is the root
8608     *                of a task; if true it will work for any activity in a task.
8609     * @return Returns true if the move completed, false if not.
8610     */
8611    @Override
8612    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8613        enforceNotIsolatedCaller("moveActivityTaskToBack");
8614        synchronized(this) {
8615            final long origId = Binder.clearCallingIdentity();
8616            try {
8617                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8618                if (taskId >= 0) {
8619                    if ((mStackSupervisor.mLockTaskModeTask != null)
8620                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8621                        mStackSupervisor.showLockTaskToast();
8622                        return false;
8623                    }
8624                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8625                }
8626            } finally {
8627                Binder.restoreCallingIdentity(origId);
8628            }
8629        }
8630        return false;
8631    }
8632
8633    @Override
8634    public void moveTaskBackwards(int task) {
8635        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8636                "moveTaskBackwards()");
8637
8638        synchronized(this) {
8639            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8640                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8641                return;
8642            }
8643            final long origId = Binder.clearCallingIdentity();
8644            moveTaskBackwardsLocked(task);
8645            Binder.restoreCallingIdentity(origId);
8646        }
8647    }
8648
8649    private final void moveTaskBackwardsLocked(int task) {
8650        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8651    }
8652
8653    @Override
8654    public IBinder getHomeActivityToken() throws RemoteException {
8655        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8656                "getHomeActivityToken()");
8657        synchronized (this) {
8658            return mStackSupervisor.getHomeActivityToken();
8659        }
8660    }
8661
8662    @Override
8663    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8664            IActivityContainerCallback callback) throws RemoteException {
8665        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8666                "createActivityContainer()");
8667        synchronized (this) {
8668            if (parentActivityToken == null) {
8669                throw new IllegalArgumentException("parent token must not be null");
8670            }
8671            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8672            if (r == null) {
8673                return null;
8674            }
8675            if (callback == null) {
8676                throw new IllegalArgumentException("callback must not be null");
8677            }
8678            return mStackSupervisor.createActivityContainer(r, callback);
8679        }
8680    }
8681
8682    @Override
8683    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8684        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8685                "deleteActivityContainer()");
8686        synchronized (this) {
8687            mStackSupervisor.deleteActivityContainer(container);
8688        }
8689    }
8690
8691    @Override
8692    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8693            throws RemoteException {
8694        synchronized (this) {
8695            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8696            if (stack != null) {
8697                return stack.mActivityContainer;
8698            }
8699            return null;
8700        }
8701    }
8702
8703    @Override
8704    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8705        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8706                "moveTaskToStack()");
8707        if (stackId == HOME_STACK_ID) {
8708            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8709                    new RuntimeException("here").fillInStackTrace());
8710        }
8711        synchronized (this) {
8712            long ident = Binder.clearCallingIdentity();
8713            try {
8714                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8715                        + stackId + " toTop=" + toTop);
8716                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8717            } finally {
8718                Binder.restoreCallingIdentity(ident);
8719            }
8720        }
8721    }
8722
8723    @Override
8724    public void resizeStack(int stackBoxId, Rect bounds) {
8725        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8726                "resizeStackBox()");
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            mWindowManager.resizeStack(stackBoxId, bounds);
8730        } finally {
8731            Binder.restoreCallingIdentity(ident);
8732        }
8733    }
8734
8735    @Override
8736    public List<StackInfo> getAllStackInfos() {
8737        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8738                "getAllStackInfos()");
8739        long ident = Binder.clearCallingIdentity();
8740        try {
8741            synchronized (this) {
8742                return mStackSupervisor.getAllStackInfosLocked();
8743            }
8744        } finally {
8745            Binder.restoreCallingIdentity(ident);
8746        }
8747    }
8748
8749    @Override
8750    public StackInfo getStackInfo(int stackId) {
8751        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8752                "getStackInfo()");
8753        long ident = Binder.clearCallingIdentity();
8754        try {
8755            synchronized (this) {
8756                return mStackSupervisor.getStackInfoLocked(stackId);
8757            }
8758        } finally {
8759            Binder.restoreCallingIdentity(ident);
8760        }
8761    }
8762
8763    @Override
8764    public boolean isInHomeStack(int taskId) {
8765        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8766                "getStackInfo()");
8767        long ident = Binder.clearCallingIdentity();
8768        try {
8769            synchronized (this) {
8770                TaskRecord tr = recentTaskForIdLocked(taskId);
8771                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8772            }
8773        } finally {
8774            Binder.restoreCallingIdentity(ident);
8775        }
8776    }
8777
8778    @Override
8779    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8780        synchronized(this) {
8781            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8782        }
8783    }
8784
8785    private boolean isLockTaskAuthorized(String pkg) {
8786        final DevicePolicyManager dpm = (DevicePolicyManager)
8787                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8788        try {
8789            int uid = mContext.getPackageManager().getPackageUid(pkg,
8790                    Binder.getCallingUserHandle().getIdentifier());
8791            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8792        } catch (NameNotFoundException e) {
8793            return false;
8794        }
8795    }
8796
8797    void startLockTaskMode(TaskRecord task) {
8798        final String pkg;
8799        synchronized (this) {
8800            pkg = task.intent.getComponent().getPackageName();
8801        }
8802        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8803        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8804            final TaskRecord taskRecord = task;
8805            mHandler.post(new Runnable() {
8806                @Override
8807                public void run() {
8808                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8809                }
8810            });
8811            return;
8812        }
8813        long ident = Binder.clearCallingIdentity();
8814        try {
8815            synchronized (this) {
8816                // Since we lost lock on task, make sure it is still there.
8817                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8818                if (task != null) {
8819                    if (!isSystemInitiated
8820                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8821                        throw new IllegalArgumentException("Invalid task, not in foreground");
8822                    }
8823                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8824                }
8825            }
8826        } finally {
8827            Binder.restoreCallingIdentity(ident);
8828        }
8829    }
8830
8831    @Override
8832    public void startLockTaskMode(int taskId) {
8833        final TaskRecord task;
8834        long ident = Binder.clearCallingIdentity();
8835        try {
8836            synchronized (this) {
8837                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8838            }
8839        } finally {
8840            Binder.restoreCallingIdentity(ident);
8841        }
8842        if (task != null) {
8843            startLockTaskMode(task);
8844        }
8845    }
8846
8847    @Override
8848    public void startLockTaskMode(IBinder token) {
8849        final TaskRecord task;
8850        long ident = Binder.clearCallingIdentity();
8851        try {
8852            synchronized (this) {
8853                final ActivityRecord r = ActivityRecord.forToken(token);
8854                if (r == null) {
8855                    return;
8856                }
8857                task = r.task;
8858            }
8859        } finally {
8860            Binder.restoreCallingIdentity(ident);
8861        }
8862        if (task != null) {
8863            startLockTaskMode(task);
8864        }
8865    }
8866
8867    @Override
8868    public void startLockTaskModeOnCurrent() throws RemoteException {
8869        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8870                "startLockTaskModeOnCurrent");
8871        ActivityRecord r = null;
8872        synchronized (this) {
8873            r = mStackSupervisor.topRunningActivityLocked();
8874        }
8875        startLockTaskMode(r.task);
8876    }
8877
8878    @Override
8879    public void stopLockTaskMode() {
8880        // Verify that the user matches the package of the intent for the TaskRecord
8881        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8882        // and stopLockTaskMode.
8883        final int callingUid = Binder.getCallingUid();
8884        if (callingUid != Process.SYSTEM_UID) {
8885            try {
8886                String pkg =
8887                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8888                int uid = mContext.getPackageManager().getPackageUid(pkg,
8889                        Binder.getCallingUserHandle().getIdentifier());
8890                if (uid != callingUid) {
8891                    throw new SecurityException("Invalid uid, expected " + uid);
8892                }
8893            } catch (NameNotFoundException e) {
8894                Log.d(TAG, "stopLockTaskMode " + e);
8895                return;
8896            }
8897        }
8898        long ident = Binder.clearCallingIdentity();
8899        try {
8900            Log.d(TAG, "stopLockTaskMode");
8901            // Stop lock task
8902            synchronized (this) {
8903                mStackSupervisor.setLockTaskModeLocked(null, false);
8904            }
8905        } finally {
8906            Binder.restoreCallingIdentity(ident);
8907        }
8908    }
8909
8910    @Override
8911    public void stopLockTaskModeOnCurrent() throws RemoteException {
8912        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8913                "stopLockTaskModeOnCurrent");
8914        long ident = Binder.clearCallingIdentity();
8915        try {
8916            stopLockTaskMode();
8917        } finally {
8918            Binder.restoreCallingIdentity(ident);
8919        }
8920    }
8921
8922    @Override
8923    public boolean isInLockTaskMode() {
8924        synchronized (this) {
8925            return mStackSupervisor.isInLockTaskMode();
8926        }
8927    }
8928
8929    // =========================================================
8930    // CONTENT PROVIDERS
8931    // =========================================================
8932
8933    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8934        List<ProviderInfo> providers = null;
8935        try {
8936            providers = AppGlobals.getPackageManager().
8937                queryContentProviders(app.processName, app.uid,
8938                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8939        } catch (RemoteException ex) {
8940        }
8941        if (DEBUG_MU)
8942            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8943        int userId = app.userId;
8944        if (providers != null) {
8945            int N = providers.size();
8946            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8947            for (int i=0; i<N; i++) {
8948                ProviderInfo cpi =
8949                    (ProviderInfo)providers.get(i);
8950                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8951                        cpi.name, cpi.flags);
8952                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8953                    // This is a singleton provider, but a user besides the
8954                    // default user is asking to initialize a process it runs
8955                    // in...  well, no, it doesn't actually run in this process,
8956                    // it runs in the process of the default user.  Get rid of it.
8957                    providers.remove(i);
8958                    N--;
8959                    i--;
8960                    continue;
8961                }
8962
8963                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8964                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8965                if (cpr == null) {
8966                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8967                    mProviderMap.putProviderByClass(comp, cpr);
8968                }
8969                if (DEBUG_MU)
8970                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8971                app.pubProviders.put(cpi.name, cpr);
8972                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8973                    // Don't add this if it is a platform component that is marked
8974                    // to run in multiple processes, because this is actually
8975                    // part of the framework so doesn't make sense to track as a
8976                    // separate apk in the process.
8977                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8978                            mProcessStats);
8979                }
8980                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8981            }
8982        }
8983        return providers;
8984    }
8985
8986    /**
8987     * Check if {@link ProcessRecord} has a possible chance at accessing the
8988     * given {@link ProviderInfo}. Final permission checking is always done
8989     * in {@link ContentProvider}.
8990     */
8991    private final String checkContentProviderPermissionLocked(
8992            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8993        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8994        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8995        boolean checkedGrants = false;
8996        if (checkUser) {
8997            // Looking for cross-user grants before enforcing the typical cross-users permissions
8998            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8999            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9000                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9001                    return null;
9002                }
9003                checkedGrants = true;
9004            }
9005            userId = handleIncomingUser(callingPid, callingUid, userId,
9006                    false, ALLOW_NON_FULL,
9007                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9008            if (userId != tmpTargetUserId) {
9009                // When we actually went to determine the final targer user ID, this ended
9010                // up different than our initial check for the authority.  This is because
9011                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9012                // SELF.  So we need to re-check the grants again.
9013                checkedGrants = false;
9014            }
9015        }
9016        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9017                cpi.applicationInfo.uid, cpi.exported)
9018                == PackageManager.PERMISSION_GRANTED) {
9019            return null;
9020        }
9021        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9022                cpi.applicationInfo.uid, cpi.exported)
9023                == PackageManager.PERMISSION_GRANTED) {
9024            return null;
9025        }
9026
9027        PathPermission[] pps = cpi.pathPermissions;
9028        if (pps != null) {
9029            int i = pps.length;
9030            while (i > 0) {
9031                i--;
9032                PathPermission pp = pps[i];
9033                String pprperm = pp.getReadPermission();
9034                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9035                        cpi.applicationInfo.uid, cpi.exported)
9036                        == PackageManager.PERMISSION_GRANTED) {
9037                    return null;
9038                }
9039                String ppwperm = pp.getWritePermission();
9040                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9041                        cpi.applicationInfo.uid, cpi.exported)
9042                        == PackageManager.PERMISSION_GRANTED) {
9043                    return null;
9044                }
9045            }
9046        }
9047        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9048            return null;
9049        }
9050
9051        String msg;
9052        if (!cpi.exported) {
9053            msg = "Permission Denial: opening provider " + cpi.name
9054                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9055                    + ", uid=" + callingUid + ") that is not exported from uid "
9056                    + cpi.applicationInfo.uid;
9057        } else {
9058            msg = "Permission Denial: opening provider " + cpi.name
9059                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9060                    + ", uid=" + callingUid + ") requires "
9061                    + cpi.readPermission + " or " + cpi.writePermission;
9062        }
9063        Slog.w(TAG, msg);
9064        return msg;
9065    }
9066
9067    /**
9068     * Returns if the ContentProvider has granted a uri to callingUid
9069     */
9070    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9071        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9072        if (perms != null) {
9073            for (int i=perms.size()-1; i>=0; i--) {
9074                GrantUri grantUri = perms.keyAt(i);
9075                if (grantUri.sourceUserId == userId || !checkUser) {
9076                    if (matchesProvider(grantUri.uri, cpi)) {
9077                        return true;
9078                    }
9079                }
9080            }
9081        }
9082        return false;
9083    }
9084
9085    /**
9086     * Returns true if the uri authority is one of the authorities specified in the provider.
9087     */
9088    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9089        String uriAuth = uri.getAuthority();
9090        String cpiAuth = cpi.authority;
9091        if (cpiAuth.indexOf(';') == -1) {
9092            return cpiAuth.equals(uriAuth);
9093        }
9094        String[] cpiAuths = cpiAuth.split(";");
9095        int length = cpiAuths.length;
9096        for (int i = 0; i < length; i++) {
9097            if (cpiAuths[i].equals(uriAuth)) return true;
9098        }
9099        return false;
9100    }
9101
9102    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9103            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9104        if (r != null) {
9105            for (int i=0; i<r.conProviders.size(); i++) {
9106                ContentProviderConnection conn = r.conProviders.get(i);
9107                if (conn.provider == cpr) {
9108                    if (DEBUG_PROVIDER) Slog.v(TAG,
9109                            "Adding provider requested by "
9110                            + r.processName + " from process "
9111                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9112                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9113                    if (stable) {
9114                        conn.stableCount++;
9115                        conn.numStableIncs++;
9116                    } else {
9117                        conn.unstableCount++;
9118                        conn.numUnstableIncs++;
9119                    }
9120                    return conn;
9121                }
9122            }
9123            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9124            if (stable) {
9125                conn.stableCount = 1;
9126                conn.numStableIncs = 1;
9127            } else {
9128                conn.unstableCount = 1;
9129                conn.numUnstableIncs = 1;
9130            }
9131            cpr.connections.add(conn);
9132            r.conProviders.add(conn);
9133            return conn;
9134        }
9135        cpr.addExternalProcessHandleLocked(externalProcessToken);
9136        return null;
9137    }
9138
9139    boolean decProviderCountLocked(ContentProviderConnection conn,
9140            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9141        if (conn != null) {
9142            cpr = conn.provider;
9143            if (DEBUG_PROVIDER) Slog.v(TAG,
9144                    "Removing provider requested by "
9145                    + conn.client.processName + " from process "
9146                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9147                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9148            if (stable) {
9149                conn.stableCount--;
9150            } else {
9151                conn.unstableCount--;
9152            }
9153            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9154                cpr.connections.remove(conn);
9155                conn.client.conProviders.remove(conn);
9156                return true;
9157            }
9158            return false;
9159        }
9160        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9161        return false;
9162    }
9163
9164    private void checkTime(long startTime, String where) {
9165        long now = SystemClock.elapsedRealtime();
9166        if ((now-startTime) > 1000) {
9167            // If we are taking more than a second, log about it.
9168            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9169        }
9170    }
9171
9172    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9173            String name, IBinder token, boolean stable, int userId) {
9174        ContentProviderRecord cpr;
9175        ContentProviderConnection conn = null;
9176        ProviderInfo cpi = null;
9177
9178        synchronized(this) {
9179            long startTime = SystemClock.elapsedRealtime();
9180
9181            ProcessRecord r = null;
9182            if (caller != null) {
9183                r = getRecordForAppLocked(caller);
9184                if (r == null) {
9185                    throw new SecurityException(
9186                            "Unable to find app for caller " + caller
9187                          + " (pid=" + Binder.getCallingPid()
9188                          + ") when getting content provider " + name);
9189                }
9190            }
9191
9192            boolean checkCrossUser = true;
9193
9194            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9195
9196            // First check if this content provider has been published...
9197            cpr = mProviderMap.getProviderByName(name, userId);
9198            // If that didn't work, check if it exists for user 0 and then
9199            // verify that it's a singleton provider before using it.
9200            if (cpr == null && userId != UserHandle.USER_OWNER) {
9201                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9202                if (cpr != null) {
9203                    cpi = cpr.info;
9204                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9205                            cpi.name, cpi.flags)
9206                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9207                        userId = UserHandle.USER_OWNER;
9208                        checkCrossUser = false;
9209                    } else {
9210                        cpr = null;
9211                        cpi = null;
9212                    }
9213                }
9214            }
9215
9216            boolean providerRunning = cpr != null;
9217            if (providerRunning) {
9218                cpi = cpr.info;
9219                String msg;
9220                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9221                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9222                        != null) {
9223                    throw new SecurityException(msg);
9224                }
9225                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9226
9227                if (r != null && cpr.canRunHere(r)) {
9228                    // This provider has been published or is in the process
9229                    // of being published...  but it is also allowed to run
9230                    // in the caller's process, so don't make a connection
9231                    // and just let the caller instantiate its own instance.
9232                    ContentProviderHolder holder = cpr.newHolder(null);
9233                    // don't give caller the provider object, it needs
9234                    // to make its own.
9235                    holder.provider = null;
9236                    return holder;
9237                }
9238
9239                final long origId = Binder.clearCallingIdentity();
9240
9241                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9242
9243                // In this case the provider instance already exists, so we can
9244                // return it right away.
9245                conn = incProviderCountLocked(r, cpr, token, stable);
9246                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9247                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9248                        // If this is a perceptible app accessing the provider,
9249                        // make sure to count it as being accessed and thus
9250                        // back up on the LRU list.  This is good because
9251                        // content providers are often expensive to start.
9252                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9253                        updateLruProcessLocked(cpr.proc, false, null);
9254                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9255                    }
9256                }
9257
9258                if (cpr.proc != null) {
9259                    if (false) {
9260                        if (cpr.name.flattenToShortString().equals(
9261                                "com.android.providers.calendar/.CalendarProvider2")) {
9262                            Slog.v(TAG, "****************** KILLING "
9263                                + cpr.name.flattenToShortString());
9264                            Process.killProcess(cpr.proc.pid);
9265                        }
9266                    }
9267                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9268                    boolean success = updateOomAdjLocked(cpr.proc);
9269                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9270                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9271                    // NOTE: there is still a race here where a signal could be
9272                    // pending on the process even though we managed to update its
9273                    // adj level.  Not sure what to do about this, but at least
9274                    // the race is now smaller.
9275                    if (!success) {
9276                        // Uh oh...  it looks like the provider's process
9277                        // has been killed on us.  We need to wait for a new
9278                        // process to be started, and make sure its death
9279                        // doesn't kill our process.
9280                        Slog.i(TAG,
9281                                "Existing provider " + cpr.name.flattenToShortString()
9282                                + " is crashing; detaching " + r);
9283                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9284                        checkTime(startTime, "getContentProviderImpl: before appDied");
9285                        appDiedLocked(cpr.proc);
9286                        checkTime(startTime, "getContentProviderImpl: after appDied");
9287                        if (!lastRef) {
9288                            // This wasn't the last ref our process had on
9289                            // the provider...  we have now been killed, bail.
9290                            return null;
9291                        }
9292                        providerRunning = false;
9293                        conn = null;
9294                    }
9295                }
9296
9297                Binder.restoreCallingIdentity(origId);
9298            }
9299
9300            boolean singleton;
9301            if (!providerRunning) {
9302                try {
9303                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9304                    cpi = AppGlobals.getPackageManager().
9305                        resolveContentProvider(name,
9306                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9307                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9308                } catch (RemoteException ex) {
9309                }
9310                if (cpi == null) {
9311                    return null;
9312                }
9313                // If the provider is a singleton AND
9314                // (it's a call within the same user || the provider is a
9315                // privileged app)
9316                // Then allow connecting to the singleton provider
9317                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9318                        cpi.name, cpi.flags)
9319                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9320                if (singleton) {
9321                    userId = UserHandle.USER_OWNER;
9322                }
9323                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9324                checkTime(startTime, "getContentProviderImpl: got app info for user");
9325
9326                String msg;
9327                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9328                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9329                        != null) {
9330                    throw new SecurityException(msg);
9331                }
9332                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9333
9334                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9335                        && !cpi.processName.equals("system")) {
9336                    // If this content provider does not run in the system
9337                    // process, and the system is not yet ready to run other
9338                    // processes, then fail fast instead of hanging.
9339                    throw new IllegalArgumentException(
9340                            "Attempt to launch content provider before system ready");
9341                }
9342
9343                // Make sure that the user who owns this provider is started.  If not,
9344                // we don't want to allow it to run.
9345                if (mStartedUsers.get(userId) == null) {
9346                    Slog.w(TAG, "Unable to launch app "
9347                            + cpi.applicationInfo.packageName + "/"
9348                            + cpi.applicationInfo.uid + " for provider "
9349                            + name + ": user " + userId + " is stopped");
9350                    return null;
9351                }
9352
9353                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9354                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9355                cpr = mProviderMap.getProviderByClass(comp, userId);
9356                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9357                final boolean firstClass = cpr == null;
9358                if (firstClass) {
9359                    final long ident = Binder.clearCallingIdentity();
9360                    try {
9361                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9362                        ApplicationInfo ai =
9363                            AppGlobals.getPackageManager().
9364                                getApplicationInfo(
9365                                        cpi.applicationInfo.packageName,
9366                                        STOCK_PM_FLAGS, userId);
9367                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9368                        if (ai == null) {
9369                            Slog.w(TAG, "No package info for content provider "
9370                                    + cpi.name);
9371                            return null;
9372                        }
9373                        ai = getAppInfoForUser(ai, userId);
9374                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9375                    } catch (RemoteException ex) {
9376                        // pm is in same process, this will never happen.
9377                    } finally {
9378                        Binder.restoreCallingIdentity(ident);
9379                    }
9380                }
9381
9382                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9383
9384                if (r != null && cpr.canRunHere(r)) {
9385                    // If this is a multiprocess provider, then just return its
9386                    // info and allow the caller to instantiate it.  Only do
9387                    // this if the provider is the same user as the caller's
9388                    // process, or can run as root (so can be in any process).
9389                    return cpr.newHolder(null);
9390                }
9391
9392                if (DEBUG_PROVIDER) {
9393                    RuntimeException e = new RuntimeException("here");
9394                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9395                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9396                }
9397
9398                // This is single process, and our app is now connecting to it.
9399                // See if we are already in the process of launching this
9400                // provider.
9401                final int N = mLaunchingProviders.size();
9402                int i;
9403                for (i=0; i<N; i++) {
9404                    if (mLaunchingProviders.get(i) == cpr) {
9405                        break;
9406                    }
9407                }
9408
9409                // If the provider is not already being launched, then get it
9410                // started.
9411                if (i >= N) {
9412                    final long origId = Binder.clearCallingIdentity();
9413
9414                    try {
9415                        // Content provider is now in use, its package can't be stopped.
9416                        try {
9417                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9418                            AppGlobals.getPackageManager().setPackageStoppedState(
9419                                    cpr.appInfo.packageName, false, userId);
9420                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9421                        } catch (RemoteException e) {
9422                        } catch (IllegalArgumentException e) {
9423                            Slog.w(TAG, "Failed trying to unstop package "
9424                                    + cpr.appInfo.packageName + ": " + e);
9425                        }
9426
9427                        // Use existing process if already started
9428                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9429                        ProcessRecord proc = getProcessRecordLocked(
9430                                cpi.processName, cpr.appInfo.uid, false);
9431                        if (proc != null && proc.thread != null) {
9432                            if (DEBUG_PROVIDER) {
9433                                Slog.d(TAG, "Installing in existing process " + proc);
9434                            }
9435                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9436                            proc.pubProviders.put(cpi.name, cpr);
9437                            try {
9438                                proc.thread.scheduleInstallProvider(cpi);
9439                            } catch (RemoteException e) {
9440                            }
9441                        } else {
9442                            checkTime(startTime, "getContentProviderImpl: before start process");
9443                            proc = startProcessLocked(cpi.processName,
9444                                    cpr.appInfo, false, 0, "content provider",
9445                                    new ComponentName(cpi.applicationInfo.packageName,
9446                                            cpi.name), false, false, false);
9447                            checkTime(startTime, "getContentProviderImpl: after start process");
9448                            if (proc == null) {
9449                                Slog.w(TAG, "Unable to launch app "
9450                                        + cpi.applicationInfo.packageName + "/"
9451                                        + cpi.applicationInfo.uid + " for provider "
9452                                        + name + ": process is bad");
9453                                return null;
9454                            }
9455                        }
9456                        cpr.launchingApp = proc;
9457                        mLaunchingProviders.add(cpr);
9458                    } finally {
9459                        Binder.restoreCallingIdentity(origId);
9460                    }
9461                }
9462
9463                checkTime(startTime, "getContentProviderImpl: updating data structures");
9464
9465                // Make sure the provider is published (the same provider class
9466                // may be published under multiple names).
9467                if (firstClass) {
9468                    mProviderMap.putProviderByClass(comp, cpr);
9469                }
9470
9471                mProviderMap.putProviderByName(name, cpr);
9472                conn = incProviderCountLocked(r, cpr, token, stable);
9473                if (conn != null) {
9474                    conn.waiting = true;
9475                }
9476            }
9477            checkTime(startTime, "getContentProviderImpl: done!");
9478        }
9479
9480        // Wait for the provider to be published...
9481        synchronized (cpr) {
9482            while (cpr.provider == null) {
9483                if (cpr.launchingApp == null) {
9484                    Slog.w(TAG, "Unable to launch app "
9485                            + cpi.applicationInfo.packageName + "/"
9486                            + cpi.applicationInfo.uid + " for provider "
9487                            + name + ": launching app became null");
9488                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9489                            UserHandle.getUserId(cpi.applicationInfo.uid),
9490                            cpi.applicationInfo.packageName,
9491                            cpi.applicationInfo.uid, name);
9492                    return null;
9493                }
9494                try {
9495                    if (DEBUG_MU) {
9496                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9497                                + cpr.launchingApp);
9498                    }
9499                    if (conn != null) {
9500                        conn.waiting = true;
9501                    }
9502                    cpr.wait();
9503                } catch (InterruptedException ex) {
9504                } finally {
9505                    if (conn != null) {
9506                        conn.waiting = false;
9507                    }
9508                }
9509            }
9510        }
9511        return cpr != null ? cpr.newHolder(conn) : null;
9512    }
9513
9514    @Override
9515    public final ContentProviderHolder getContentProvider(
9516            IApplicationThread caller, String name, int userId, boolean stable) {
9517        enforceNotIsolatedCaller("getContentProvider");
9518        if (caller == null) {
9519            String msg = "null IApplicationThread when getting content provider "
9520                    + name;
9521            Slog.w(TAG, msg);
9522            throw new SecurityException(msg);
9523        }
9524        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9525        // with cross-user grant.
9526        return getContentProviderImpl(caller, name, null, stable, userId);
9527    }
9528
9529    public ContentProviderHolder getContentProviderExternal(
9530            String name, int userId, IBinder token) {
9531        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9532            "Do not have permission in call getContentProviderExternal()");
9533        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9534                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9535        return getContentProviderExternalUnchecked(name, token, userId);
9536    }
9537
9538    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9539            IBinder token, int userId) {
9540        return getContentProviderImpl(null, name, token, true, userId);
9541    }
9542
9543    /**
9544     * Drop a content provider from a ProcessRecord's bookkeeping
9545     */
9546    public void removeContentProvider(IBinder connection, boolean stable) {
9547        enforceNotIsolatedCaller("removeContentProvider");
9548        long ident = Binder.clearCallingIdentity();
9549        try {
9550            synchronized (this) {
9551                ContentProviderConnection conn;
9552                try {
9553                    conn = (ContentProviderConnection)connection;
9554                } catch (ClassCastException e) {
9555                    String msg ="removeContentProvider: " + connection
9556                            + " not a ContentProviderConnection";
9557                    Slog.w(TAG, msg);
9558                    throw new IllegalArgumentException(msg);
9559                }
9560                if (conn == null) {
9561                    throw new NullPointerException("connection is null");
9562                }
9563                if (decProviderCountLocked(conn, null, null, stable)) {
9564                    updateOomAdjLocked();
9565                }
9566            }
9567        } finally {
9568            Binder.restoreCallingIdentity(ident);
9569        }
9570    }
9571
9572    public void removeContentProviderExternal(String name, IBinder token) {
9573        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9574            "Do not have permission in call removeContentProviderExternal()");
9575        int userId = UserHandle.getCallingUserId();
9576        long ident = Binder.clearCallingIdentity();
9577        try {
9578            removeContentProviderExternalUnchecked(name, token, userId);
9579        } finally {
9580            Binder.restoreCallingIdentity(ident);
9581        }
9582    }
9583
9584    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9585        synchronized (this) {
9586            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9587            if(cpr == null) {
9588                //remove from mProvidersByClass
9589                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9590                return;
9591            }
9592
9593            //update content provider record entry info
9594            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9595            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9596            if (localCpr.hasExternalProcessHandles()) {
9597                if (localCpr.removeExternalProcessHandleLocked(token)) {
9598                    updateOomAdjLocked();
9599                } else {
9600                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9601                            + " with no external reference for token: "
9602                            + token + ".");
9603                }
9604            } else {
9605                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9606                        + " with no external references.");
9607            }
9608        }
9609    }
9610
9611    public final void publishContentProviders(IApplicationThread caller,
9612            List<ContentProviderHolder> providers) {
9613        if (providers == null) {
9614            return;
9615        }
9616
9617        enforceNotIsolatedCaller("publishContentProviders");
9618        synchronized (this) {
9619            final ProcessRecord r = getRecordForAppLocked(caller);
9620            if (DEBUG_MU)
9621                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9622            if (r == null) {
9623                throw new SecurityException(
9624                        "Unable to find app for caller " + caller
9625                      + " (pid=" + Binder.getCallingPid()
9626                      + ") when publishing content providers");
9627            }
9628
9629            final long origId = Binder.clearCallingIdentity();
9630
9631            final int N = providers.size();
9632            for (int i=0; i<N; i++) {
9633                ContentProviderHolder src = providers.get(i);
9634                if (src == null || src.info == null || src.provider == null) {
9635                    continue;
9636                }
9637                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9638                if (DEBUG_MU)
9639                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9640                if (dst != null) {
9641                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9642                    mProviderMap.putProviderByClass(comp, dst);
9643                    String names[] = dst.info.authority.split(";");
9644                    for (int j = 0; j < names.length; j++) {
9645                        mProviderMap.putProviderByName(names[j], dst);
9646                    }
9647
9648                    int NL = mLaunchingProviders.size();
9649                    int j;
9650                    for (j=0; j<NL; j++) {
9651                        if (mLaunchingProviders.get(j) == dst) {
9652                            mLaunchingProviders.remove(j);
9653                            j--;
9654                            NL--;
9655                        }
9656                    }
9657                    synchronized (dst) {
9658                        dst.provider = src.provider;
9659                        dst.proc = r;
9660                        dst.notifyAll();
9661                    }
9662                    updateOomAdjLocked(r);
9663                }
9664            }
9665
9666            Binder.restoreCallingIdentity(origId);
9667        }
9668    }
9669
9670    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9671        ContentProviderConnection conn;
9672        try {
9673            conn = (ContentProviderConnection)connection;
9674        } catch (ClassCastException e) {
9675            String msg ="refContentProvider: " + connection
9676                    + " not a ContentProviderConnection";
9677            Slog.w(TAG, msg);
9678            throw new IllegalArgumentException(msg);
9679        }
9680        if (conn == null) {
9681            throw new NullPointerException("connection is null");
9682        }
9683
9684        synchronized (this) {
9685            if (stable > 0) {
9686                conn.numStableIncs += stable;
9687            }
9688            stable = conn.stableCount + stable;
9689            if (stable < 0) {
9690                throw new IllegalStateException("stableCount < 0: " + stable);
9691            }
9692
9693            if (unstable > 0) {
9694                conn.numUnstableIncs += unstable;
9695            }
9696            unstable = conn.unstableCount + unstable;
9697            if (unstable < 0) {
9698                throw new IllegalStateException("unstableCount < 0: " + unstable);
9699            }
9700
9701            if ((stable+unstable) <= 0) {
9702                throw new IllegalStateException("ref counts can't go to zero here: stable="
9703                        + stable + " unstable=" + unstable);
9704            }
9705            conn.stableCount = stable;
9706            conn.unstableCount = unstable;
9707            return !conn.dead;
9708        }
9709    }
9710
9711    public void unstableProviderDied(IBinder connection) {
9712        ContentProviderConnection conn;
9713        try {
9714            conn = (ContentProviderConnection)connection;
9715        } catch (ClassCastException e) {
9716            String msg ="refContentProvider: " + connection
9717                    + " not a ContentProviderConnection";
9718            Slog.w(TAG, msg);
9719            throw new IllegalArgumentException(msg);
9720        }
9721        if (conn == null) {
9722            throw new NullPointerException("connection is null");
9723        }
9724
9725        // Safely retrieve the content provider associated with the connection.
9726        IContentProvider provider;
9727        synchronized (this) {
9728            provider = conn.provider.provider;
9729        }
9730
9731        if (provider == null) {
9732            // Um, yeah, we're way ahead of you.
9733            return;
9734        }
9735
9736        // Make sure the caller is being honest with us.
9737        if (provider.asBinder().pingBinder()) {
9738            // Er, no, still looks good to us.
9739            synchronized (this) {
9740                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9741                        + " says " + conn + " died, but we don't agree");
9742                return;
9743            }
9744        }
9745
9746        // Well look at that!  It's dead!
9747        synchronized (this) {
9748            if (conn.provider.provider != provider) {
9749                // But something changed...  good enough.
9750                return;
9751            }
9752
9753            ProcessRecord proc = conn.provider.proc;
9754            if (proc == null || proc.thread == null) {
9755                // Seems like the process is already cleaned up.
9756                return;
9757            }
9758
9759            // As far as we're concerned, this is just like receiving a
9760            // death notification...  just a bit prematurely.
9761            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9762                    + ") early provider death");
9763            final long ident = Binder.clearCallingIdentity();
9764            try {
9765                appDiedLocked(proc);
9766            } finally {
9767                Binder.restoreCallingIdentity(ident);
9768            }
9769        }
9770    }
9771
9772    @Override
9773    public void appNotRespondingViaProvider(IBinder connection) {
9774        enforceCallingPermission(
9775                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9776
9777        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9778        if (conn == null) {
9779            Slog.w(TAG, "ContentProviderConnection is null");
9780            return;
9781        }
9782
9783        final ProcessRecord host = conn.provider.proc;
9784        if (host == null) {
9785            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9786            return;
9787        }
9788
9789        final long token = Binder.clearCallingIdentity();
9790        try {
9791            appNotResponding(host, null, null, false, "ContentProvider not responding");
9792        } finally {
9793            Binder.restoreCallingIdentity(token);
9794        }
9795    }
9796
9797    public final void installSystemProviders() {
9798        List<ProviderInfo> providers;
9799        synchronized (this) {
9800            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9801            providers = generateApplicationProvidersLocked(app);
9802            if (providers != null) {
9803                for (int i=providers.size()-1; i>=0; i--) {
9804                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9805                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9806                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9807                                + ": not system .apk");
9808                        providers.remove(i);
9809                    }
9810                }
9811            }
9812        }
9813        if (providers != null) {
9814            mSystemThread.installSystemProviders(providers);
9815        }
9816
9817        mCoreSettingsObserver = new CoreSettingsObserver(this);
9818
9819        //mUsageStatsService.monitorPackages();
9820    }
9821
9822    /**
9823     * Allows apps to retrieve the MIME type of a URI.
9824     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9825     * users, then it does not need permission to access the ContentProvider.
9826     * Either, it needs cross-user uri grants.
9827     *
9828     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9829     *
9830     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9831     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9832     */
9833    public String getProviderMimeType(Uri uri, int userId) {
9834        enforceNotIsolatedCaller("getProviderMimeType");
9835        final String name = uri.getAuthority();
9836        int callingUid = Binder.getCallingUid();
9837        int callingPid = Binder.getCallingPid();
9838        long ident = 0;
9839        boolean clearedIdentity = false;
9840        userId = unsafeConvertIncomingUser(userId);
9841        if (canClearIdentity(callingPid, callingUid, userId)) {
9842            clearedIdentity = true;
9843            ident = Binder.clearCallingIdentity();
9844        }
9845        ContentProviderHolder holder = null;
9846        try {
9847            holder = getContentProviderExternalUnchecked(name, null, userId);
9848            if (holder != null) {
9849                return holder.provider.getType(uri);
9850            }
9851        } catch (RemoteException e) {
9852            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9853            return null;
9854        } finally {
9855            // We need to clear the identity to call removeContentProviderExternalUnchecked
9856            if (!clearedIdentity) {
9857                ident = Binder.clearCallingIdentity();
9858            }
9859            try {
9860                if (holder != null) {
9861                    removeContentProviderExternalUnchecked(name, null, userId);
9862                }
9863            } finally {
9864                Binder.restoreCallingIdentity(ident);
9865            }
9866        }
9867
9868        return null;
9869    }
9870
9871    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9872        if (UserHandle.getUserId(callingUid) == userId) {
9873            return true;
9874        }
9875        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9876                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9877                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9878                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9879                return true;
9880        }
9881        return false;
9882    }
9883
9884    // =========================================================
9885    // GLOBAL MANAGEMENT
9886    // =========================================================
9887
9888    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9889            boolean isolated, int isolatedUid) {
9890        String proc = customProcess != null ? customProcess : info.processName;
9891        BatteryStatsImpl.Uid.Proc ps = null;
9892        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9893        int uid = info.uid;
9894        if (isolated) {
9895            if (isolatedUid == 0) {
9896                int userId = UserHandle.getUserId(uid);
9897                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9898                while (true) {
9899                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9900                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9901                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9902                    }
9903                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9904                    mNextIsolatedProcessUid++;
9905                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9906                        // No process for this uid, use it.
9907                        break;
9908                    }
9909                    stepsLeft--;
9910                    if (stepsLeft <= 0) {
9911                        return null;
9912                    }
9913                }
9914            } else {
9915                // Special case for startIsolatedProcess (internal only), where
9916                // the uid of the isolated process is specified by the caller.
9917                uid = isolatedUid;
9918            }
9919        }
9920        return new ProcessRecord(stats, info, proc, uid);
9921    }
9922
9923    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9924            String abiOverride) {
9925        ProcessRecord app;
9926        if (!isolated) {
9927            app = getProcessRecordLocked(info.processName, info.uid, true);
9928        } else {
9929            app = null;
9930        }
9931
9932        if (app == null) {
9933            app = newProcessRecordLocked(info, null, isolated, 0);
9934            mProcessNames.put(info.processName, app.uid, app);
9935            if (isolated) {
9936                mIsolatedProcesses.put(app.uid, app);
9937            }
9938            updateLruProcessLocked(app, false, null);
9939            updateOomAdjLocked();
9940        }
9941
9942        // This package really, really can not be stopped.
9943        try {
9944            AppGlobals.getPackageManager().setPackageStoppedState(
9945                    info.packageName, false, UserHandle.getUserId(app.uid));
9946        } catch (RemoteException e) {
9947        } catch (IllegalArgumentException e) {
9948            Slog.w(TAG, "Failed trying to unstop package "
9949                    + info.packageName + ": " + e);
9950        }
9951
9952        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9953                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9954            app.persistent = true;
9955            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9956        }
9957        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9958            mPersistentStartingProcesses.add(app);
9959            startProcessLocked(app, "added application", app.processName, abiOverride,
9960                    null /* entryPoint */, null /* entryPointArgs */);
9961        }
9962
9963        return app;
9964    }
9965
9966    public void unhandledBack() {
9967        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9968                "unhandledBack()");
9969
9970        synchronized(this) {
9971            final long origId = Binder.clearCallingIdentity();
9972            try {
9973                getFocusedStack().unhandledBackLocked();
9974            } finally {
9975                Binder.restoreCallingIdentity(origId);
9976            }
9977        }
9978    }
9979
9980    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9981        enforceNotIsolatedCaller("openContentUri");
9982        final int userId = UserHandle.getCallingUserId();
9983        String name = uri.getAuthority();
9984        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9985        ParcelFileDescriptor pfd = null;
9986        if (cph != null) {
9987            // We record the binder invoker's uid in thread-local storage before
9988            // going to the content provider to open the file.  Later, in the code
9989            // that handles all permissions checks, we look for this uid and use
9990            // that rather than the Activity Manager's own uid.  The effect is that
9991            // we do the check against the caller's permissions even though it looks
9992            // to the content provider like the Activity Manager itself is making
9993            // the request.
9994            sCallerIdentity.set(new Identity(
9995                    Binder.getCallingPid(), Binder.getCallingUid()));
9996            try {
9997                pfd = cph.provider.openFile(null, uri, "r", null);
9998            } catch (FileNotFoundException e) {
9999                // do nothing; pfd will be returned null
10000            } finally {
10001                // Ensure that whatever happens, we clean up the identity state
10002                sCallerIdentity.remove();
10003            }
10004
10005            // We've got the fd now, so we're done with the provider.
10006            removeContentProviderExternalUnchecked(name, null, userId);
10007        } else {
10008            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10009        }
10010        return pfd;
10011    }
10012
10013    // Actually is sleeping or shutting down or whatever else in the future
10014    // is an inactive state.
10015    public boolean isSleepingOrShuttingDown() {
10016        return isSleeping() || mShuttingDown;
10017    }
10018
10019    public boolean isSleeping() {
10020        return mSleeping;
10021    }
10022
10023    void goingToSleep() {
10024        synchronized(this) {
10025            mWentToSleep = true;
10026            goToSleepIfNeededLocked();
10027        }
10028    }
10029
10030    void finishRunningVoiceLocked() {
10031        if (mRunningVoice) {
10032            mRunningVoice = false;
10033            goToSleepIfNeededLocked();
10034        }
10035    }
10036
10037    void goToSleepIfNeededLocked() {
10038        if (mWentToSleep && !mRunningVoice) {
10039            if (!mSleeping) {
10040                mSleeping = true;
10041                mStackSupervisor.goingToSleepLocked();
10042
10043                // Initialize the wake times of all processes.
10044                checkExcessivePowerUsageLocked(false);
10045                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10046                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10047                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10048            }
10049        }
10050    }
10051
10052    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10053        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10054            // Never persist the home stack.
10055            return;
10056        }
10057        mTaskPersister.wakeup(task, flush);
10058    }
10059
10060    @Override
10061    public boolean shutdown(int timeout) {
10062        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10063                != PackageManager.PERMISSION_GRANTED) {
10064            throw new SecurityException("Requires permission "
10065                    + android.Manifest.permission.SHUTDOWN);
10066        }
10067
10068        boolean timedout = false;
10069
10070        synchronized(this) {
10071            mShuttingDown = true;
10072            updateEventDispatchingLocked();
10073            timedout = mStackSupervisor.shutdownLocked(timeout);
10074        }
10075
10076        mAppOpsService.shutdown();
10077        if (mUsageStatsService != null) {
10078            mUsageStatsService.prepareShutdown();
10079        }
10080        mBatteryStatsService.shutdown();
10081        synchronized (this) {
10082            mProcessStats.shutdownLocked();
10083        }
10084        notifyTaskPersisterLocked(null, true);
10085
10086        return timedout;
10087    }
10088
10089    public final void activitySlept(IBinder token) {
10090        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10091
10092        final long origId = Binder.clearCallingIdentity();
10093
10094        synchronized (this) {
10095            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10096            if (r != null) {
10097                mStackSupervisor.activitySleptLocked(r);
10098            }
10099        }
10100
10101        Binder.restoreCallingIdentity(origId);
10102    }
10103
10104    void logLockScreen(String msg) {
10105        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10106                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10107                mWentToSleep + " mSleeping=" + mSleeping);
10108    }
10109
10110    private void comeOutOfSleepIfNeededLocked() {
10111        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10112            if (mSleeping) {
10113                mSleeping = false;
10114                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10115            }
10116        }
10117    }
10118
10119    void wakingUp() {
10120        synchronized(this) {
10121            mWentToSleep = false;
10122            comeOutOfSleepIfNeededLocked();
10123        }
10124    }
10125
10126    void startRunningVoiceLocked() {
10127        if (!mRunningVoice) {
10128            mRunningVoice = true;
10129            comeOutOfSleepIfNeededLocked();
10130        }
10131    }
10132
10133    private void updateEventDispatchingLocked() {
10134        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10135    }
10136
10137    public void setLockScreenShown(boolean shown) {
10138        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10139                != PackageManager.PERMISSION_GRANTED) {
10140            throw new SecurityException("Requires permission "
10141                    + android.Manifest.permission.DEVICE_POWER);
10142        }
10143
10144        synchronized(this) {
10145            long ident = Binder.clearCallingIdentity();
10146            try {
10147                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10148                mLockScreenShown = shown;
10149                comeOutOfSleepIfNeededLocked();
10150            } finally {
10151                Binder.restoreCallingIdentity(ident);
10152            }
10153        }
10154    }
10155
10156    @Override
10157    public void stopAppSwitches() {
10158        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10159                != PackageManager.PERMISSION_GRANTED) {
10160            throw new SecurityException("Requires permission "
10161                    + android.Manifest.permission.STOP_APP_SWITCHES);
10162        }
10163
10164        synchronized(this) {
10165            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10166                    + APP_SWITCH_DELAY_TIME;
10167            mDidAppSwitch = false;
10168            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10169            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10170            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10171        }
10172    }
10173
10174    public void resumeAppSwitches() {
10175        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10176                != PackageManager.PERMISSION_GRANTED) {
10177            throw new SecurityException("Requires permission "
10178                    + android.Manifest.permission.STOP_APP_SWITCHES);
10179        }
10180
10181        synchronized(this) {
10182            // Note that we don't execute any pending app switches... we will
10183            // let those wait until either the timeout, or the next start
10184            // activity request.
10185            mAppSwitchesAllowedTime = 0;
10186        }
10187    }
10188
10189    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10190            int callingPid, int callingUid, String name) {
10191        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10192            return true;
10193        }
10194
10195        int perm = checkComponentPermission(
10196                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10197                sourceUid, -1, true);
10198        if (perm == PackageManager.PERMISSION_GRANTED) {
10199            return true;
10200        }
10201
10202        // If the actual IPC caller is different from the logical source, then
10203        // also see if they are allowed to control app switches.
10204        if (callingUid != -1 && callingUid != sourceUid) {
10205            perm = checkComponentPermission(
10206                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10207                    callingUid, -1, true);
10208            if (perm == PackageManager.PERMISSION_GRANTED) {
10209                return true;
10210            }
10211        }
10212
10213        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10214        return false;
10215    }
10216
10217    public void setDebugApp(String packageName, boolean waitForDebugger,
10218            boolean persistent) {
10219        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10220                "setDebugApp()");
10221
10222        long ident = Binder.clearCallingIdentity();
10223        try {
10224            // Note that this is not really thread safe if there are multiple
10225            // callers into it at the same time, but that's not a situation we
10226            // care about.
10227            if (persistent) {
10228                final ContentResolver resolver = mContext.getContentResolver();
10229                Settings.Global.putString(
10230                    resolver, Settings.Global.DEBUG_APP,
10231                    packageName);
10232                Settings.Global.putInt(
10233                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10234                    waitForDebugger ? 1 : 0);
10235            }
10236
10237            synchronized (this) {
10238                if (!persistent) {
10239                    mOrigDebugApp = mDebugApp;
10240                    mOrigWaitForDebugger = mWaitForDebugger;
10241                }
10242                mDebugApp = packageName;
10243                mWaitForDebugger = waitForDebugger;
10244                mDebugTransient = !persistent;
10245                if (packageName != null) {
10246                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10247                            false, UserHandle.USER_ALL, "set debug app");
10248                }
10249            }
10250        } finally {
10251            Binder.restoreCallingIdentity(ident);
10252        }
10253    }
10254
10255    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10256        synchronized (this) {
10257            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10258            if (!isDebuggable) {
10259                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10260                    throw new SecurityException("Process not debuggable: " + app.packageName);
10261                }
10262            }
10263
10264            mOpenGlTraceApp = processName;
10265        }
10266    }
10267
10268    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10269        synchronized (this) {
10270            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10271            if (!isDebuggable) {
10272                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10273                    throw new SecurityException("Process not debuggable: " + app.packageName);
10274                }
10275            }
10276            mProfileApp = processName;
10277            mProfileFile = profilerInfo.profileFile;
10278            if (mProfileFd != null) {
10279                try {
10280                    mProfileFd.close();
10281                } catch (IOException e) {
10282                }
10283                mProfileFd = null;
10284            }
10285            mProfileFd = profilerInfo.profileFd;
10286            mSamplingInterval = profilerInfo.samplingInterval;
10287            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10288            mProfileType = 0;
10289        }
10290    }
10291
10292    @Override
10293    public void setAlwaysFinish(boolean enabled) {
10294        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10295                "setAlwaysFinish()");
10296
10297        Settings.Global.putInt(
10298                mContext.getContentResolver(),
10299                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10300
10301        synchronized (this) {
10302            mAlwaysFinishActivities = enabled;
10303        }
10304    }
10305
10306    @Override
10307    public void setActivityController(IActivityController controller) {
10308        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10309                "setActivityController()");
10310        synchronized (this) {
10311            mController = controller;
10312            Watchdog.getInstance().setActivityController(controller);
10313        }
10314    }
10315
10316    @Override
10317    public void setUserIsMonkey(boolean userIsMonkey) {
10318        synchronized (this) {
10319            synchronized (mPidsSelfLocked) {
10320                final int callingPid = Binder.getCallingPid();
10321                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10322                if (precessRecord == null) {
10323                    throw new SecurityException("Unknown process: " + callingPid);
10324                }
10325                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10326                    throw new SecurityException("Only an instrumentation process "
10327                            + "with a UiAutomation can call setUserIsMonkey");
10328                }
10329            }
10330            mUserIsMonkey = userIsMonkey;
10331        }
10332    }
10333
10334    @Override
10335    public boolean isUserAMonkey() {
10336        synchronized (this) {
10337            // If there is a controller also implies the user is a monkey.
10338            return (mUserIsMonkey || mController != null);
10339        }
10340    }
10341
10342    public void requestBugReport() {
10343        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10344        SystemProperties.set("ctl.start", "bugreport");
10345    }
10346
10347    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10348        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10349    }
10350
10351    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10352        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10353            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10354        }
10355        return KEY_DISPATCHING_TIMEOUT;
10356    }
10357
10358    @Override
10359    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10360        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10361                != PackageManager.PERMISSION_GRANTED) {
10362            throw new SecurityException("Requires permission "
10363                    + android.Manifest.permission.FILTER_EVENTS);
10364        }
10365        ProcessRecord proc;
10366        long timeout;
10367        synchronized (this) {
10368            synchronized (mPidsSelfLocked) {
10369                proc = mPidsSelfLocked.get(pid);
10370            }
10371            timeout = getInputDispatchingTimeoutLocked(proc);
10372        }
10373
10374        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10375            return -1;
10376        }
10377
10378        return timeout;
10379    }
10380
10381    /**
10382     * Handle input dispatching timeouts.
10383     * Returns whether input dispatching should be aborted or not.
10384     */
10385    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10386            final ActivityRecord activity, final ActivityRecord parent,
10387            final boolean aboveSystem, String reason) {
10388        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10389                != PackageManager.PERMISSION_GRANTED) {
10390            throw new SecurityException("Requires permission "
10391                    + android.Manifest.permission.FILTER_EVENTS);
10392        }
10393
10394        final String annotation;
10395        if (reason == null) {
10396            annotation = "Input dispatching timed out";
10397        } else {
10398            annotation = "Input dispatching timed out (" + reason + ")";
10399        }
10400
10401        if (proc != null) {
10402            synchronized (this) {
10403                if (proc.debugging) {
10404                    return false;
10405                }
10406
10407                if (mDidDexOpt) {
10408                    // Give more time since we were dexopting.
10409                    mDidDexOpt = false;
10410                    return false;
10411                }
10412
10413                if (proc.instrumentationClass != null) {
10414                    Bundle info = new Bundle();
10415                    info.putString("shortMsg", "keyDispatchingTimedOut");
10416                    info.putString("longMsg", annotation);
10417                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10418                    return true;
10419                }
10420            }
10421            mHandler.post(new Runnable() {
10422                @Override
10423                public void run() {
10424                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10425                }
10426            });
10427        }
10428
10429        return true;
10430    }
10431
10432    public Bundle getAssistContextExtras(int requestType) {
10433        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10434                "getAssistContextExtras()");
10435        PendingAssistExtras pae;
10436        Bundle extras = new Bundle();
10437        synchronized (this) {
10438            ActivityRecord activity = getFocusedStack().mResumedActivity;
10439            if (activity == null) {
10440                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10441                return null;
10442            }
10443            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10444            if (activity.app == null || activity.app.thread == null) {
10445                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10446                return extras;
10447            }
10448            if (activity.app.pid == Binder.getCallingPid()) {
10449                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10450                return extras;
10451            }
10452            pae = new PendingAssistExtras(activity);
10453            try {
10454                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10455                        requestType);
10456                mPendingAssistExtras.add(pae);
10457                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10458            } catch (RemoteException e) {
10459                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10460                return extras;
10461            }
10462        }
10463        synchronized (pae) {
10464            while (!pae.haveResult) {
10465                try {
10466                    pae.wait();
10467                } catch (InterruptedException e) {
10468                }
10469            }
10470            if (pae.result != null) {
10471                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10472            }
10473        }
10474        synchronized (this) {
10475            mPendingAssistExtras.remove(pae);
10476            mHandler.removeCallbacks(pae);
10477        }
10478        return extras;
10479    }
10480
10481    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10482        PendingAssistExtras pae = (PendingAssistExtras)token;
10483        synchronized (pae) {
10484            pae.result = extras;
10485            pae.haveResult = true;
10486            pae.notifyAll();
10487        }
10488    }
10489
10490    public void registerProcessObserver(IProcessObserver observer) {
10491        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10492                "registerProcessObserver()");
10493        synchronized (this) {
10494            mProcessObservers.register(observer);
10495        }
10496    }
10497
10498    @Override
10499    public void unregisterProcessObserver(IProcessObserver observer) {
10500        synchronized (this) {
10501            mProcessObservers.unregister(observer);
10502        }
10503    }
10504
10505    @Override
10506    public boolean convertFromTranslucent(IBinder token) {
10507        final long origId = Binder.clearCallingIdentity();
10508        try {
10509            synchronized (this) {
10510                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10511                if (r == null) {
10512                    return false;
10513                }
10514                final boolean translucentChanged = r.changeWindowTranslucency(true);
10515                if (translucentChanged) {
10516                    r.task.stack.releaseBackgroundResources();
10517                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10518                }
10519                mWindowManager.setAppFullscreen(token, true);
10520                return translucentChanged;
10521            }
10522        } finally {
10523            Binder.restoreCallingIdentity(origId);
10524        }
10525    }
10526
10527    @Override
10528    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10529        final long origId = Binder.clearCallingIdentity();
10530        try {
10531            synchronized (this) {
10532                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10533                if (r == null) {
10534                    return false;
10535                }
10536                int index = r.task.mActivities.lastIndexOf(r);
10537                if (index > 0) {
10538                    ActivityRecord under = r.task.mActivities.get(index - 1);
10539                    under.returningOptions = options;
10540                }
10541                final boolean translucentChanged = r.changeWindowTranslucency(false);
10542                if (translucentChanged) {
10543                    r.task.stack.convertToTranslucent(r);
10544                }
10545                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10546                mWindowManager.setAppFullscreen(token, false);
10547                return translucentChanged;
10548            }
10549        } finally {
10550            Binder.restoreCallingIdentity(origId);
10551        }
10552    }
10553
10554    @Override
10555    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10556        final long origId = Binder.clearCallingIdentity();
10557        try {
10558            synchronized (this) {
10559                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10560                if (r != null) {
10561                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10562                }
10563            }
10564            return false;
10565        } finally {
10566            Binder.restoreCallingIdentity(origId);
10567        }
10568    }
10569
10570    @Override
10571    public boolean isBackgroundVisibleBehind(IBinder token) {
10572        final long origId = Binder.clearCallingIdentity();
10573        try {
10574            synchronized (this) {
10575                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10576                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10577                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10578                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10579                return visible;
10580            }
10581        } finally {
10582            Binder.restoreCallingIdentity(origId);
10583        }
10584    }
10585
10586    @Override
10587    public ActivityOptions getActivityOptions(IBinder token) {
10588        final long origId = Binder.clearCallingIdentity();
10589        try {
10590            synchronized (this) {
10591                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10592                if (r != null) {
10593                    final ActivityOptions activityOptions = r.pendingOptions;
10594                    r.pendingOptions = null;
10595                    return activityOptions;
10596                }
10597                return null;
10598            }
10599        } finally {
10600            Binder.restoreCallingIdentity(origId);
10601        }
10602    }
10603
10604    @Override
10605    public void setImmersive(IBinder token, boolean immersive) {
10606        synchronized(this) {
10607            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10608            if (r == null) {
10609                throw new IllegalArgumentException();
10610            }
10611            r.immersive = immersive;
10612
10613            // update associated state if we're frontmost
10614            if (r == mFocusedActivity) {
10615                if (DEBUG_IMMERSIVE) {
10616                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10617                }
10618                applyUpdateLockStateLocked(r);
10619            }
10620        }
10621    }
10622
10623    @Override
10624    public boolean isImmersive(IBinder token) {
10625        synchronized (this) {
10626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10627            if (r == null) {
10628                throw new IllegalArgumentException();
10629            }
10630            return r.immersive;
10631        }
10632    }
10633
10634    public boolean isTopActivityImmersive() {
10635        enforceNotIsolatedCaller("startActivity");
10636        synchronized (this) {
10637            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10638            return (r != null) ? r.immersive : false;
10639        }
10640    }
10641
10642    @Override
10643    public boolean isTopOfTask(IBinder token) {
10644        synchronized (this) {
10645            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10646            if (r == null) {
10647                throw new IllegalArgumentException();
10648            }
10649            return r.task.getTopActivity() == r;
10650        }
10651    }
10652
10653    public final void enterSafeMode() {
10654        synchronized(this) {
10655            // It only makes sense to do this before the system is ready
10656            // and started launching other packages.
10657            if (!mSystemReady) {
10658                try {
10659                    AppGlobals.getPackageManager().enterSafeMode();
10660                } catch (RemoteException e) {
10661                }
10662            }
10663
10664            mSafeMode = true;
10665        }
10666    }
10667
10668    public final void showSafeModeOverlay() {
10669        View v = LayoutInflater.from(mContext).inflate(
10670                com.android.internal.R.layout.safe_mode, null);
10671        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10672        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10673        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10674        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10675        lp.gravity = Gravity.BOTTOM | Gravity.START;
10676        lp.format = v.getBackground().getOpacity();
10677        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10678                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10679        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10680        ((WindowManager)mContext.getSystemService(
10681                Context.WINDOW_SERVICE)).addView(v, lp);
10682    }
10683
10684    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10685        if (!(sender instanceof PendingIntentRecord)) {
10686            return;
10687        }
10688        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10689        synchronized (stats) {
10690            if (mBatteryStatsService.isOnBattery()) {
10691                mBatteryStatsService.enforceCallingPermission();
10692                PendingIntentRecord rec = (PendingIntentRecord)sender;
10693                int MY_UID = Binder.getCallingUid();
10694                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10695                BatteryStatsImpl.Uid.Pkg pkg =
10696                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10697                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10698                pkg.incWakeupsLocked();
10699            }
10700        }
10701    }
10702
10703    public boolean killPids(int[] pids, String pReason, boolean secure) {
10704        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10705            throw new SecurityException("killPids only available to the system");
10706        }
10707        String reason = (pReason == null) ? "Unknown" : pReason;
10708        // XXX Note: don't acquire main activity lock here, because the window
10709        // manager calls in with its locks held.
10710
10711        boolean killed = false;
10712        synchronized (mPidsSelfLocked) {
10713            int[] types = new int[pids.length];
10714            int worstType = 0;
10715            for (int i=0; i<pids.length; i++) {
10716                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10717                if (proc != null) {
10718                    int type = proc.setAdj;
10719                    types[i] = type;
10720                    if (type > worstType) {
10721                        worstType = type;
10722                    }
10723                }
10724            }
10725
10726            // If the worst oom_adj is somewhere in the cached proc LRU range,
10727            // then constrain it so we will kill all cached procs.
10728            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10729                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10730                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10731            }
10732
10733            // If this is not a secure call, don't let it kill processes that
10734            // are important.
10735            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10736                worstType = ProcessList.SERVICE_ADJ;
10737            }
10738
10739            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10740            for (int i=0; i<pids.length; i++) {
10741                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10742                if (proc == null) {
10743                    continue;
10744                }
10745                int adj = proc.setAdj;
10746                if (adj >= worstType && !proc.killedByAm) {
10747                    proc.kill(reason, true);
10748                    killed = true;
10749                }
10750            }
10751        }
10752        return killed;
10753    }
10754
10755    @Override
10756    public void killUid(int uid, String reason) {
10757        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10758            throw new SecurityException("killUid only available to the system");
10759        }
10760        synchronized (this) {
10761            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10762                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10763                    reason != null ? reason : "kill uid");
10764        }
10765    }
10766
10767    @Override
10768    public boolean killProcessesBelowForeground(String reason) {
10769        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10770            throw new SecurityException("killProcessesBelowForeground() only available to system");
10771        }
10772
10773        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10774    }
10775
10776    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10777        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10778            throw new SecurityException("killProcessesBelowAdj() only available to system");
10779        }
10780
10781        boolean killed = false;
10782        synchronized (mPidsSelfLocked) {
10783            final int size = mPidsSelfLocked.size();
10784            for (int i = 0; i < size; i++) {
10785                final int pid = mPidsSelfLocked.keyAt(i);
10786                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10787                if (proc == null) continue;
10788
10789                final int adj = proc.setAdj;
10790                if (adj > belowAdj && !proc.killedByAm) {
10791                    proc.kill(reason, true);
10792                    killed = true;
10793                }
10794            }
10795        }
10796        return killed;
10797    }
10798
10799    @Override
10800    public void hang(final IBinder who, boolean allowRestart) {
10801        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10802                != PackageManager.PERMISSION_GRANTED) {
10803            throw new SecurityException("Requires permission "
10804                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10805        }
10806
10807        final IBinder.DeathRecipient death = new DeathRecipient() {
10808            @Override
10809            public void binderDied() {
10810                synchronized (this) {
10811                    notifyAll();
10812                }
10813            }
10814        };
10815
10816        try {
10817            who.linkToDeath(death, 0);
10818        } catch (RemoteException e) {
10819            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10820            return;
10821        }
10822
10823        synchronized (this) {
10824            Watchdog.getInstance().setAllowRestart(allowRestart);
10825            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10826            synchronized (death) {
10827                while (who.isBinderAlive()) {
10828                    try {
10829                        death.wait();
10830                    } catch (InterruptedException e) {
10831                    }
10832                }
10833            }
10834            Watchdog.getInstance().setAllowRestart(true);
10835        }
10836    }
10837
10838    @Override
10839    public void restart() {
10840        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10841                != PackageManager.PERMISSION_GRANTED) {
10842            throw new SecurityException("Requires permission "
10843                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10844        }
10845
10846        Log.i(TAG, "Sending shutdown broadcast...");
10847
10848        BroadcastReceiver br = new BroadcastReceiver() {
10849            @Override public void onReceive(Context context, Intent intent) {
10850                // Now the broadcast is done, finish up the low-level shutdown.
10851                Log.i(TAG, "Shutting down activity manager...");
10852                shutdown(10000);
10853                Log.i(TAG, "Shutdown complete, restarting!");
10854                Process.killProcess(Process.myPid());
10855                System.exit(10);
10856            }
10857        };
10858
10859        // First send the high-level shut down broadcast.
10860        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10861        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10862        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10863        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10864        mContext.sendOrderedBroadcastAsUser(intent,
10865                UserHandle.ALL, null, br, mHandler, 0, null, null);
10866        */
10867        br.onReceive(mContext, intent);
10868    }
10869
10870    private long getLowRamTimeSinceIdle(long now) {
10871        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10872    }
10873
10874    @Override
10875    public void performIdleMaintenance() {
10876        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10877                != PackageManager.PERMISSION_GRANTED) {
10878            throw new SecurityException("Requires permission "
10879                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10880        }
10881
10882        synchronized (this) {
10883            final long now = SystemClock.uptimeMillis();
10884            final long timeSinceLastIdle = now - mLastIdleTime;
10885            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10886            mLastIdleTime = now;
10887            mLowRamTimeSinceLastIdle = 0;
10888            if (mLowRamStartTime != 0) {
10889                mLowRamStartTime = now;
10890            }
10891
10892            StringBuilder sb = new StringBuilder(128);
10893            sb.append("Idle maintenance over ");
10894            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10895            sb.append(" low RAM for ");
10896            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10897            Slog.i(TAG, sb.toString());
10898
10899            // If at least 1/3 of our time since the last idle period has been spent
10900            // with RAM low, then we want to kill processes.
10901            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10902
10903            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10904                ProcessRecord proc = mLruProcesses.get(i);
10905                if (proc.notCachedSinceIdle) {
10906                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10907                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10908                        if (doKilling && proc.initialIdlePss != 0
10909                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10910                            proc.kill("idle maint (pss " + proc.lastPss
10911                                    + " from " + proc.initialIdlePss + ")", true);
10912                        }
10913                    }
10914                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10915                    proc.notCachedSinceIdle = true;
10916                    proc.initialIdlePss = 0;
10917                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10918                            isSleeping(), now);
10919                }
10920            }
10921
10922            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10923            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10924        }
10925    }
10926
10927    private void retrieveSettings() {
10928        final ContentResolver resolver = mContext.getContentResolver();
10929        String debugApp = Settings.Global.getString(
10930            resolver, Settings.Global.DEBUG_APP);
10931        boolean waitForDebugger = Settings.Global.getInt(
10932            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10933        boolean alwaysFinishActivities = Settings.Global.getInt(
10934            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10935        boolean forceRtl = Settings.Global.getInt(
10936                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10937        // Transfer any global setting for forcing RTL layout, into a System Property
10938        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10939
10940        Configuration configuration = new Configuration();
10941        Settings.System.getConfiguration(resolver, configuration);
10942        if (forceRtl) {
10943            // This will take care of setting the correct layout direction flags
10944            configuration.setLayoutDirection(configuration.locale);
10945        }
10946
10947        synchronized (this) {
10948            mDebugApp = mOrigDebugApp = debugApp;
10949            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10950            mAlwaysFinishActivities = alwaysFinishActivities;
10951            // This happens before any activities are started, so we can
10952            // change mConfiguration in-place.
10953            updateConfigurationLocked(configuration, null, false, true);
10954            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10955        }
10956    }
10957
10958    /** Loads resources after the current configuration has been set. */
10959    private void loadResourcesOnSystemReady() {
10960        final Resources res = mContext.getResources();
10961        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10962        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10963        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10964    }
10965
10966    public boolean testIsSystemReady() {
10967        // no need to synchronize(this) just to read & return the value
10968        return mSystemReady;
10969    }
10970
10971    private static File getCalledPreBootReceiversFile() {
10972        File dataDir = Environment.getDataDirectory();
10973        File systemDir = new File(dataDir, "system");
10974        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10975        return fname;
10976    }
10977
10978    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10979        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10980        File file = getCalledPreBootReceiversFile();
10981        FileInputStream fis = null;
10982        try {
10983            fis = new FileInputStream(file);
10984            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10985            int fvers = dis.readInt();
10986            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10987                String vers = dis.readUTF();
10988                String codename = dis.readUTF();
10989                String build = dis.readUTF();
10990                if (android.os.Build.VERSION.RELEASE.equals(vers)
10991                        && android.os.Build.VERSION.CODENAME.equals(codename)
10992                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10993                    int num = dis.readInt();
10994                    while (num > 0) {
10995                        num--;
10996                        String pkg = dis.readUTF();
10997                        String cls = dis.readUTF();
10998                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10999                    }
11000                }
11001            }
11002        } catch (FileNotFoundException e) {
11003        } catch (IOException e) {
11004            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11005        } finally {
11006            if (fis != null) {
11007                try {
11008                    fis.close();
11009                } catch (IOException e) {
11010                }
11011            }
11012        }
11013        return lastDoneReceivers;
11014    }
11015
11016    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11017        File file = getCalledPreBootReceiversFile();
11018        FileOutputStream fos = null;
11019        DataOutputStream dos = null;
11020        try {
11021            fos = new FileOutputStream(file);
11022            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11023            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11024            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11025            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11026            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11027            dos.writeInt(list.size());
11028            for (int i=0; i<list.size(); i++) {
11029                dos.writeUTF(list.get(i).getPackageName());
11030                dos.writeUTF(list.get(i).getClassName());
11031            }
11032        } catch (IOException e) {
11033            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11034            file.delete();
11035        } finally {
11036            FileUtils.sync(fos);
11037            if (dos != null) {
11038                try {
11039                    dos.close();
11040                } catch (IOException e) {
11041                    // TODO Auto-generated catch block
11042                    e.printStackTrace();
11043                }
11044            }
11045        }
11046    }
11047
11048    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11049            ArrayList<ComponentName> doneReceivers, int userId) {
11050        boolean waitingUpdate = false;
11051        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11052        List<ResolveInfo> ris = null;
11053        try {
11054            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11055                    intent, null, 0, userId);
11056        } catch (RemoteException e) {
11057        }
11058        if (ris != null) {
11059            for (int i=ris.size()-1; i>=0; i--) {
11060                if ((ris.get(i).activityInfo.applicationInfo.flags
11061                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11062                    ris.remove(i);
11063                }
11064            }
11065            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11066
11067            // For User 0, load the version number. When delivering to a new user, deliver
11068            // to all receivers.
11069            if (userId == UserHandle.USER_OWNER) {
11070                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11071                for (int i=0; i<ris.size(); i++) {
11072                    ActivityInfo ai = ris.get(i).activityInfo;
11073                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11074                    if (lastDoneReceivers.contains(comp)) {
11075                        // We already did the pre boot receiver for this app with the current
11076                        // platform version, so don't do it again...
11077                        ris.remove(i);
11078                        i--;
11079                        // ...however, do keep it as one that has been done, so we don't
11080                        // forget about it when rewriting the file of last done receivers.
11081                        doneReceivers.add(comp);
11082                    }
11083                }
11084            }
11085
11086            // If primary user, send broadcast to all available users, else just to userId
11087            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11088                    : new int[] { userId };
11089            for (int i = 0; i < ris.size(); i++) {
11090                ActivityInfo ai = ris.get(i).activityInfo;
11091                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11092                doneReceivers.add(comp);
11093                intent.setComponent(comp);
11094                for (int j=0; j<users.length; j++) {
11095                    IIntentReceiver finisher = null;
11096                    // On last receiver and user, set up a completion callback
11097                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11098                        finisher = new IIntentReceiver.Stub() {
11099                            public void performReceive(Intent intent, int resultCode,
11100                                    String data, Bundle extras, boolean ordered,
11101                                    boolean sticky, int sendingUser) {
11102                                // The raw IIntentReceiver interface is called
11103                                // with the AM lock held, so redispatch to
11104                                // execute our code without the lock.
11105                                mHandler.post(onFinishCallback);
11106                            }
11107                        };
11108                    }
11109                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11110                            + " for user " + users[j]);
11111                    broadcastIntentLocked(null, null, intent, null, finisher,
11112                            0, null, null, null, AppOpsManager.OP_NONE,
11113                            true, false, MY_PID, Process.SYSTEM_UID,
11114                            users[j]);
11115                    if (finisher != null) {
11116                        waitingUpdate = true;
11117                    }
11118                }
11119            }
11120        }
11121
11122        return waitingUpdate;
11123    }
11124
11125    public void systemReady(final Runnable goingCallback) {
11126        synchronized(this) {
11127            if (mSystemReady) {
11128                // If we're done calling all the receivers, run the next "boot phase" passed in
11129                // by the SystemServer
11130                if (goingCallback != null) {
11131                    goingCallback.run();
11132                }
11133                return;
11134            }
11135
11136            // Make sure we have the current profile info, since it is needed for
11137            // security checks.
11138            updateCurrentProfileIdsLocked();
11139
11140            if (mRecentTasks == null) {
11141                mRecentTasks = mTaskPersister.restoreTasksLocked();
11142                if (!mRecentTasks.isEmpty()) {
11143                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11144                }
11145                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11146                mTaskPersister.startPersisting();
11147            }
11148
11149            // Check to see if there are any update receivers to run.
11150            if (!mDidUpdate) {
11151                if (mWaitingUpdate) {
11152                    return;
11153                }
11154                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11155                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11156                    public void run() {
11157                        synchronized (ActivityManagerService.this) {
11158                            mDidUpdate = true;
11159                        }
11160                        writeLastDonePreBootReceivers(doneReceivers);
11161                        showBootMessage(mContext.getText(
11162                                R.string.android_upgrading_complete),
11163                                false);
11164                        systemReady(goingCallback);
11165                    }
11166                }, doneReceivers, UserHandle.USER_OWNER);
11167
11168                if (mWaitingUpdate) {
11169                    return;
11170                }
11171                mDidUpdate = true;
11172            }
11173
11174            mAppOpsService.systemReady();
11175            mSystemReady = true;
11176        }
11177
11178        ArrayList<ProcessRecord> procsToKill = null;
11179        synchronized(mPidsSelfLocked) {
11180            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11181                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11182                if (!isAllowedWhileBooting(proc.info)){
11183                    if (procsToKill == null) {
11184                        procsToKill = new ArrayList<ProcessRecord>();
11185                    }
11186                    procsToKill.add(proc);
11187                }
11188            }
11189        }
11190
11191        synchronized(this) {
11192            if (procsToKill != null) {
11193                for (int i=procsToKill.size()-1; i>=0; i--) {
11194                    ProcessRecord proc = procsToKill.get(i);
11195                    Slog.i(TAG, "Removing system update proc: " + proc);
11196                    removeProcessLocked(proc, true, false, "system update done");
11197                }
11198            }
11199
11200            // Now that we have cleaned up any update processes, we
11201            // are ready to start launching real processes and know that
11202            // we won't trample on them any more.
11203            mProcessesReady = true;
11204        }
11205
11206        Slog.i(TAG, "System now ready");
11207        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11208            SystemClock.uptimeMillis());
11209
11210        synchronized(this) {
11211            // Make sure we have no pre-ready processes sitting around.
11212
11213            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11214                ResolveInfo ri = mContext.getPackageManager()
11215                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11216                                STOCK_PM_FLAGS);
11217                CharSequence errorMsg = null;
11218                if (ri != null) {
11219                    ActivityInfo ai = ri.activityInfo;
11220                    ApplicationInfo app = ai.applicationInfo;
11221                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11222                        mTopAction = Intent.ACTION_FACTORY_TEST;
11223                        mTopData = null;
11224                        mTopComponent = new ComponentName(app.packageName,
11225                                ai.name);
11226                    } else {
11227                        errorMsg = mContext.getResources().getText(
11228                                com.android.internal.R.string.factorytest_not_system);
11229                    }
11230                } else {
11231                    errorMsg = mContext.getResources().getText(
11232                            com.android.internal.R.string.factorytest_no_action);
11233                }
11234                if (errorMsg != null) {
11235                    mTopAction = null;
11236                    mTopData = null;
11237                    mTopComponent = null;
11238                    Message msg = Message.obtain();
11239                    msg.what = SHOW_FACTORY_ERROR_MSG;
11240                    msg.getData().putCharSequence("msg", errorMsg);
11241                    mHandler.sendMessage(msg);
11242                }
11243            }
11244        }
11245
11246        retrieveSettings();
11247        loadResourcesOnSystemReady();
11248
11249        synchronized (this) {
11250            readGrantedUriPermissionsLocked();
11251        }
11252
11253        if (goingCallback != null) goingCallback.run();
11254
11255        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11256                Integer.toString(mCurrentUserId), mCurrentUserId);
11257        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11258                Integer.toString(mCurrentUserId), mCurrentUserId);
11259        mSystemServiceManager.startUser(mCurrentUserId);
11260
11261        synchronized (this) {
11262            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11263                try {
11264                    List apps = AppGlobals.getPackageManager().
11265                        getPersistentApplications(STOCK_PM_FLAGS);
11266                    if (apps != null) {
11267                        int N = apps.size();
11268                        int i;
11269                        for (i=0; i<N; i++) {
11270                            ApplicationInfo info
11271                                = (ApplicationInfo)apps.get(i);
11272                            if (info != null &&
11273                                    !info.packageName.equals("android")) {
11274                                addAppLocked(info, false, null /* ABI override */);
11275                            }
11276                        }
11277                    }
11278                } catch (RemoteException ex) {
11279                    // pm is in same process, this will never happen.
11280                }
11281            }
11282
11283            // Start up initial activity.
11284            mBooting = true;
11285            startHomeActivityLocked(mCurrentUserId);
11286
11287            try {
11288                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11289                    Message msg = Message.obtain();
11290                    msg.what = SHOW_UID_ERROR_MSG;
11291                    mHandler.sendMessage(msg);
11292                }
11293            } catch (RemoteException e) {
11294            }
11295
11296            long ident = Binder.clearCallingIdentity();
11297            try {
11298                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11299                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11300                        | Intent.FLAG_RECEIVER_FOREGROUND);
11301                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11302                broadcastIntentLocked(null, null, intent,
11303                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11304                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11305                intent = new Intent(Intent.ACTION_USER_STARTING);
11306                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11307                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11308                broadcastIntentLocked(null, null, intent,
11309                        null, new IIntentReceiver.Stub() {
11310                            @Override
11311                            public void performReceive(Intent intent, int resultCode, String data,
11312                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11313                                    throws RemoteException {
11314                            }
11315                        }, 0, null, null,
11316                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11317                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11318            } catch (Throwable t) {
11319                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11320            } finally {
11321                Binder.restoreCallingIdentity(ident);
11322            }
11323            mStackSupervisor.resumeTopActivitiesLocked();
11324            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11325        }
11326    }
11327
11328    private boolean makeAppCrashingLocked(ProcessRecord app,
11329            String shortMsg, String longMsg, String stackTrace) {
11330        app.crashing = true;
11331        app.crashingReport = generateProcessError(app,
11332                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11333        startAppProblemLocked(app);
11334        app.stopFreezingAllLocked();
11335        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11336    }
11337
11338    private void makeAppNotRespondingLocked(ProcessRecord app,
11339            String activity, String shortMsg, String longMsg) {
11340        app.notResponding = true;
11341        app.notRespondingReport = generateProcessError(app,
11342                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11343                activity, shortMsg, longMsg, null);
11344        startAppProblemLocked(app);
11345        app.stopFreezingAllLocked();
11346    }
11347
11348    /**
11349     * Generate a process error record, suitable for attachment to a ProcessRecord.
11350     *
11351     * @param app The ProcessRecord in which the error occurred.
11352     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11353     *                      ActivityManager.AppErrorStateInfo
11354     * @param activity The activity associated with the crash, if known.
11355     * @param shortMsg Short message describing the crash.
11356     * @param longMsg Long message describing the crash.
11357     * @param stackTrace Full crash stack trace, may be null.
11358     *
11359     * @return Returns a fully-formed AppErrorStateInfo record.
11360     */
11361    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11362            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11363        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11364
11365        report.condition = condition;
11366        report.processName = app.processName;
11367        report.pid = app.pid;
11368        report.uid = app.info.uid;
11369        report.tag = activity;
11370        report.shortMsg = shortMsg;
11371        report.longMsg = longMsg;
11372        report.stackTrace = stackTrace;
11373
11374        return report;
11375    }
11376
11377    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11378        synchronized (this) {
11379            app.crashing = false;
11380            app.crashingReport = null;
11381            app.notResponding = false;
11382            app.notRespondingReport = null;
11383            if (app.anrDialog == fromDialog) {
11384                app.anrDialog = null;
11385            }
11386            if (app.waitDialog == fromDialog) {
11387                app.waitDialog = null;
11388            }
11389            if (app.pid > 0 && app.pid != MY_PID) {
11390                handleAppCrashLocked(app, null, null, null);
11391                app.kill("user request after error", true);
11392            }
11393        }
11394    }
11395
11396    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11397            String stackTrace) {
11398        long now = SystemClock.uptimeMillis();
11399
11400        Long crashTime;
11401        if (!app.isolated) {
11402            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11403        } else {
11404            crashTime = null;
11405        }
11406        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11407            // This process loses!
11408            Slog.w(TAG, "Process " + app.info.processName
11409                    + " has crashed too many times: killing!");
11410            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11411                    app.userId, app.info.processName, app.uid);
11412            mStackSupervisor.handleAppCrashLocked(app);
11413            if (!app.persistent) {
11414                // We don't want to start this process again until the user
11415                // explicitly does so...  but for persistent process, we really
11416                // need to keep it running.  If a persistent process is actually
11417                // repeatedly crashing, then badness for everyone.
11418                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11419                        app.info.processName);
11420                if (!app.isolated) {
11421                    // XXX We don't have a way to mark isolated processes
11422                    // as bad, since they don't have a peristent identity.
11423                    mBadProcesses.put(app.info.processName, app.uid,
11424                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11425                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11426                }
11427                app.bad = true;
11428                app.removed = true;
11429                // Don't let services in this process be restarted and potentially
11430                // annoy the user repeatedly.  Unless it is persistent, since those
11431                // processes run critical code.
11432                removeProcessLocked(app, false, false, "crash");
11433                mStackSupervisor.resumeTopActivitiesLocked();
11434                return false;
11435            }
11436            mStackSupervisor.resumeTopActivitiesLocked();
11437        } else {
11438            mStackSupervisor.finishTopRunningActivityLocked(app);
11439        }
11440
11441        // Bump up the crash count of any services currently running in the proc.
11442        for (int i=app.services.size()-1; i>=0; i--) {
11443            // Any services running in the application need to be placed
11444            // back in the pending list.
11445            ServiceRecord sr = app.services.valueAt(i);
11446            sr.crashCount++;
11447        }
11448
11449        // If the crashing process is what we consider to be the "home process" and it has been
11450        // replaced by a third-party app, clear the package preferred activities from packages
11451        // with a home activity running in the process to prevent a repeatedly crashing app
11452        // from blocking the user to manually clear the list.
11453        final ArrayList<ActivityRecord> activities = app.activities;
11454        if (app == mHomeProcess && activities.size() > 0
11455                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11456            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11457                final ActivityRecord r = activities.get(activityNdx);
11458                if (r.isHomeActivity()) {
11459                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11460                    try {
11461                        ActivityThread.getPackageManager()
11462                                .clearPackagePreferredActivities(r.packageName);
11463                    } catch (RemoteException c) {
11464                        // pm is in same process, this will never happen.
11465                    }
11466                }
11467            }
11468        }
11469
11470        if (!app.isolated) {
11471            // XXX Can't keep track of crash times for isolated processes,
11472            // because they don't have a perisistent identity.
11473            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11474        }
11475
11476        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11477        return true;
11478    }
11479
11480    void startAppProblemLocked(ProcessRecord app) {
11481        // If this app is not running under the current user, then we
11482        // can't give it a report button because that would require
11483        // launching the report UI under a different user.
11484        app.errorReportReceiver = null;
11485
11486        for (int userId : mCurrentProfileIds) {
11487            if (app.userId == userId) {
11488                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11489                        mContext, app.info.packageName, app.info.flags);
11490            }
11491        }
11492        skipCurrentReceiverLocked(app);
11493    }
11494
11495    void skipCurrentReceiverLocked(ProcessRecord app) {
11496        for (BroadcastQueue queue : mBroadcastQueues) {
11497            queue.skipCurrentReceiverLocked(app);
11498        }
11499    }
11500
11501    /**
11502     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11503     * The application process will exit immediately after this call returns.
11504     * @param app object of the crashing app, null for the system server
11505     * @param crashInfo describing the exception
11506     */
11507    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11508        ProcessRecord r = findAppProcess(app, "Crash");
11509        final String processName = app == null ? "system_server"
11510                : (r == null ? "unknown" : r.processName);
11511
11512        handleApplicationCrashInner("crash", r, processName, crashInfo);
11513    }
11514
11515    /* Native crash reporting uses this inner version because it needs to be somewhat
11516     * decoupled from the AM-managed cleanup lifecycle
11517     */
11518    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11519            ApplicationErrorReport.CrashInfo crashInfo) {
11520        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11521                UserHandle.getUserId(Binder.getCallingUid()), processName,
11522                r == null ? -1 : r.info.flags,
11523                crashInfo.exceptionClassName,
11524                crashInfo.exceptionMessage,
11525                crashInfo.throwFileName,
11526                crashInfo.throwLineNumber);
11527
11528        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11529
11530        crashApplication(r, crashInfo);
11531    }
11532
11533    public void handleApplicationStrictModeViolation(
11534            IBinder app,
11535            int violationMask,
11536            StrictMode.ViolationInfo info) {
11537        ProcessRecord r = findAppProcess(app, "StrictMode");
11538        if (r == null) {
11539            return;
11540        }
11541
11542        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11543            Integer stackFingerprint = info.hashCode();
11544            boolean logIt = true;
11545            synchronized (mAlreadyLoggedViolatedStacks) {
11546                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11547                    logIt = false;
11548                    // TODO: sub-sample into EventLog for these, with
11549                    // the info.durationMillis?  Then we'd get
11550                    // the relative pain numbers, without logging all
11551                    // the stack traces repeatedly.  We'd want to do
11552                    // likewise in the client code, which also does
11553                    // dup suppression, before the Binder call.
11554                } else {
11555                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11556                        mAlreadyLoggedViolatedStacks.clear();
11557                    }
11558                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11559                }
11560            }
11561            if (logIt) {
11562                logStrictModeViolationToDropBox(r, info);
11563            }
11564        }
11565
11566        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11567            AppErrorResult result = new AppErrorResult();
11568            synchronized (this) {
11569                final long origId = Binder.clearCallingIdentity();
11570
11571                Message msg = Message.obtain();
11572                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11573                HashMap<String, Object> data = new HashMap<String, Object>();
11574                data.put("result", result);
11575                data.put("app", r);
11576                data.put("violationMask", violationMask);
11577                data.put("info", info);
11578                msg.obj = data;
11579                mHandler.sendMessage(msg);
11580
11581                Binder.restoreCallingIdentity(origId);
11582            }
11583            int res = result.get();
11584            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11585        }
11586    }
11587
11588    // Depending on the policy in effect, there could be a bunch of
11589    // these in quick succession so we try to batch these together to
11590    // minimize disk writes, number of dropbox entries, and maximize
11591    // compression, by having more fewer, larger records.
11592    private void logStrictModeViolationToDropBox(
11593            ProcessRecord process,
11594            StrictMode.ViolationInfo info) {
11595        if (info == null) {
11596            return;
11597        }
11598        final boolean isSystemApp = process == null ||
11599                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11600                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11601        final String processName = process == null ? "unknown" : process.processName;
11602        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11603        final DropBoxManager dbox = (DropBoxManager)
11604                mContext.getSystemService(Context.DROPBOX_SERVICE);
11605
11606        // Exit early if the dropbox isn't configured to accept this report type.
11607        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11608
11609        boolean bufferWasEmpty;
11610        boolean needsFlush;
11611        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11612        synchronized (sb) {
11613            bufferWasEmpty = sb.length() == 0;
11614            appendDropBoxProcessHeaders(process, processName, sb);
11615            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11616            sb.append("System-App: ").append(isSystemApp).append("\n");
11617            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11618            if (info.violationNumThisLoop != 0) {
11619                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11620            }
11621            if (info.numAnimationsRunning != 0) {
11622                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11623            }
11624            if (info.broadcastIntentAction != null) {
11625                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11626            }
11627            if (info.durationMillis != -1) {
11628                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11629            }
11630            if (info.numInstances != -1) {
11631                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11632            }
11633            if (info.tags != null) {
11634                for (String tag : info.tags) {
11635                    sb.append("Span-Tag: ").append(tag).append("\n");
11636                }
11637            }
11638            sb.append("\n");
11639            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11640                sb.append(info.crashInfo.stackTrace);
11641            }
11642            sb.append("\n");
11643
11644            // Only buffer up to ~64k.  Various logging bits truncate
11645            // things at 128k.
11646            needsFlush = (sb.length() > 64 * 1024);
11647        }
11648
11649        // Flush immediately if the buffer's grown too large, or this
11650        // is a non-system app.  Non-system apps are isolated with a
11651        // different tag & policy and not batched.
11652        //
11653        // Batching is useful during internal testing with
11654        // StrictMode settings turned up high.  Without batching,
11655        // thousands of separate files could be created on boot.
11656        if (!isSystemApp || needsFlush) {
11657            new Thread("Error dump: " + dropboxTag) {
11658                @Override
11659                public void run() {
11660                    String report;
11661                    synchronized (sb) {
11662                        report = sb.toString();
11663                        sb.delete(0, sb.length());
11664                        sb.trimToSize();
11665                    }
11666                    if (report.length() != 0) {
11667                        dbox.addText(dropboxTag, report);
11668                    }
11669                }
11670            }.start();
11671            return;
11672        }
11673
11674        // System app batching:
11675        if (!bufferWasEmpty) {
11676            // An existing dropbox-writing thread is outstanding, so
11677            // we don't need to start it up.  The existing thread will
11678            // catch the buffer appends we just did.
11679            return;
11680        }
11681
11682        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11683        // (After this point, we shouldn't access AMS internal data structures.)
11684        new Thread("Error dump: " + dropboxTag) {
11685            @Override
11686            public void run() {
11687                // 5 second sleep to let stacks arrive and be batched together
11688                try {
11689                    Thread.sleep(5000);  // 5 seconds
11690                } catch (InterruptedException e) {}
11691
11692                String errorReport;
11693                synchronized (mStrictModeBuffer) {
11694                    errorReport = mStrictModeBuffer.toString();
11695                    if (errorReport.length() == 0) {
11696                        return;
11697                    }
11698                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11699                    mStrictModeBuffer.trimToSize();
11700                }
11701                dbox.addText(dropboxTag, errorReport);
11702            }
11703        }.start();
11704    }
11705
11706    /**
11707     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11708     * @param app object of the crashing app, null for the system server
11709     * @param tag reported by the caller
11710     * @param system whether this wtf is coming from the system
11711     * @param crashInfo describing the context of the error
11712     * @return true if the process should exit immediately (WTF is fatal)
11713     */
11714    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11715            final ApplicationErrorReport.CrashInfo crashInfo) {
11716        final ProcessRecord r = findAppProcess(app, "WTF");
11717        final String processName = app == null ? "system_server"
11718                : (r == null ? "unknown" : r.processName);
11719
11720        EventLog.writeEvent(EventLogTags.AM_WTF,
11721                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11722                processName,
11723                r == null ? -1 : r.info.flags,
11724                tag, crashInfo.exceptionMessage);
11725
11726        if (system) {
11727            // If this is coming from the system, we could very well have low-level
11728            // system locks held, so we want to do this all asynchronously.  And we
11729            // never want this to become fatal, so there is that too.
11730            mHandler.post(new Runnable() {
11731                @Override public void run() {
11732                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11733                            crashInfo);
11734                }
11735            });
11736            return false;
11737        }
11738
11739        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11740
11741        if (r != null && r.pid != Process.myPid() &&
11742                Settings.Global.getInt(mContext.getContentResolver(),
11743                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11744            crashApplication(r, crashInfo);
11745            return true;
11746        } else {
11747            return false;
11748        }
11749    }
11750
11751    /**
11752     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11753     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11754     */
11755    private ProcessRecord findAppProcess(IBinder app, String reason) {
11756        if (app == null) {
11757            return null;
11758        }
11759
11760        synchronized (this) {
11761            final int NP = mProcessNames.getMap().size();
11762            for (int ip=0; ip<NP; ip++) {
11763                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11764                final int NA = apps.size();
11765                for (int ia=0; ia<NA; ia++) {
11766                    ProcessRecord p = apps.valueAt(ia);
11767                    if (p.thread != null && p.thread.asBinder() == app) {
11768                        return p;
11769                    }
11770                }
11771            }
11772
11773            Slog.w(TAG, "Can't find mystery application for " + reason
11774                    + " from pid=" + Binder.getCallingPid()
11775                    + " uid=" + Binder.getCallingUid() + ": " + app);
11776            return null;
11777        }
11778    }
11779
11780    /**
11781     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11782     * to append various headers to the dropbox log text.
11783     */
11784    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11785            StringBuilder sb) {
11786        // Watchdog thread ends up invoking this function (with
11787        // a null ProcessRecord) to add the stack file to dropbox.
11788        // Do not acquire a lock on this (am) in such cases, as it
11789        // could cause a potential deadlock, if and when watchdog
11790        // is invoked due to unavailability of lock on am and it
11791        // would prevent watchdog from killing system_server.
11792        if (process == null) {
11793            sb.append("Process: ").append(processName).append("\n");
11794            return;
11795        }
11796        // Note: ProcessRecord 'process' is guarded by the service
11797        // instance.  (notably process.pkgList, which could otherwise change
11798        // concurrently during execution of this method)
11799        synchronized (this) {
11800            sb.append("Process: ").append(processName).append("\n");
11801            int flags = process.info.flags;
11802            IPackageManager pm = AppGlobals.getPackageManager();
11803            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11804            for (int ip=0; ip<process.pkgList.size(); ip++) {
11805                String pkg = process.pkgList.keyAt(ip);
11806                sb.append("Package: ").append(pkg);
11807                try {
11808                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11809                    if (pi != null) {
11810                        sb.append(" v").append(pi.versionCode);
11811                        if (pi.versionName != null) {
11812                            sb.append(" (").append(pi.versionName).append(")");
11813                        }
11814                    }
11815                } catch (RemoteException e) {
11816                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11817                }
11818                sb.append("\n");
11819            }
11820        }
11821    }
11822
11823    private static String processClass(ProcessRecord process) {
11824        if (process == null || process.pid == MY_PID) {
11825            return "system_server";
11826        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11827            return "system_app";
11828        } else {
11829            return "data_app";
11830        }
11831    }
11832
11833    /**
11834     * Write a description of an error (crash, WTF, ANR) to the drop box.
11835     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11836     * @param process which caused the error, null means the system server
11837     * @param activity which triggered the error, null if unknown
11838     * @param parent activity related to the error, null if unknown
11839     * @param subject line related to the error, null if absent
11840     * @param report in long form describing the error, null if absent
11841     * @param logFile to include in the report, null if none
11842     * @param crashInfo giving an application stack trace, null if absent
11843     */
11844    public void addErrorToDropBox(String eventType,
11845            ProcessRecord process, String processName, ActivityRecord activity,
11846            ActivityRecord parent, String subject,
11847            final String report, final File logFile,
11848            final ApplicationErrorReport.CrashInfo crashInfo) {
11849        // NOTE -- this must never acquire the ActivityManagerService lock,
11850        // otherwise the watchdog may be prevented from resetting the system.
11851
11852        final String dropboxTag = processClass(process) + "_" + eventType;
11853        final DropBoxManager dbox = (DropBoxManager)
11854                mContext.getSystemService(Context.DROPBOX_SERVICE);
11855
11856        // Exit early if the dropbox isn't configured to accept this report type.
11857        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11858
11859        final StringBuilder sb = new StringBuilder(1024);
11860        appendDropBoxProcessHeaders(process, processName, sb);
11861        if (activity != null) {
11862            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11863        }
11864        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11865            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11866        }
11867        if (parent != null && parent != activity) {
11868            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11869        }
11870        if (subject != null) {
11871            sb.append("Subject: ").append(subject).append("\n");
11872        }
11873        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11874        if (Debug.isDebuggerConnected()) {
11875            sb.append("Debugger: Connected\n");
11876        }
11877        sb.append("\n");
11878
11879        // Do the rest in a worker thread to avoid blocking the caller on I/O
11880        // (After this point, we shouldn't access AMS internal data structures.)
11881        Thread worker = new Thread("Error dump: " + dropboxTag) {
11882            @Override
11883            public void run() {
11884                if (report != null) {
11885                    sb.append(report);
11886                }
11887                if (logFile != null) {
11888                    try {
11889                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11890                                    "\n\n[[TRUNCATED]]"));
11891                    } catch (IOException e) {
11892                        Slog.e(TAG, "Error reading " + logFile, e);
11893                    }
11894                }
11895                if (crashInfo != null && crashInfo.stackTrace != null) {
11896                    sb.append(crashInfo.stackTrace);
11897                }
11898
11899                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11900                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11901                if (lines > 0) {
11902                    sb.append("\n");
11903
11904                    // Merge several logcat streams, and take the last N lines
11905                    InputStreamReader input = null;
11906                    try {
11907                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11908                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11909                                "-b", "crash",
11910                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11911
11912                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11913                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11914                        input = new InputStreamReader(logcat.getInputStream());
11915
11916                        int num;
11917                        char[] buf = new char[8192];
11918                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11919                    } catch (IOException e) {
11920                        Slog.e(TAG, "Error running logcat", e);
11921                    } finally {
11922                        if (input != null) try { input.close(); } catch (IOException e) {}
11923                    }
11924                }
11925
11926                dbox.addText(dropboxTag, sb.toString());
11927            }
11928        };
11929
11930        if (process == null) {
11931            // If process is null, we are being called from some internal code
11932            // and may be about to die -- run this synchronously.
11933            worker.run();
11934        } else {
11935            worker.start();
11936        }
11937    }
11938
11939    /**
11940     * Bring up the "unexpected error" dialog box for a crashing app.
11941     * Deal with edge cases (intercepts from instrumented applications,
11942     * ActivityController, error intent receivers, that sort of thing).
11943     * @param r the application crashing
11944     * @param crashInfo describing the failure
11945     */
11946    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11947        long timeMillis = System.currentTimeMillis();
11948        String shortMsg = crashInfo.exceptionClassName;
11949        String longMsg = crashInfo.exceptionMessage;
11950        String stackTrace = crashInfo.stackTrace;
11951        if (shortMsg != null && longMsg != null) {
11952            longMsg = shortMsg + ": " + longMsg;
11953        } else if (shortMsg != null) {
11954            longMsg = shortMsg;
11955        }
11956
11957        AppErrorResult result = new AppErrorResult();
11958        synchronized (this) {
11959            if (mController != null) {
11960                try {
11961                    String name = r != null ? r.processName : null;
11962                    int pid = r != null ? r.pid : Binder.getCallingPid();
11963                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11964                    if (!mController.appCrashed(name, pid,
11965                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11966                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11967                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11968                            Slog.w(TAG, "Skip killing native crashed app " + name
11969                                    + "(" + pid + ") during testing");
11970                        } else {
11971                            Slog.w(TAG, "Force-killing crashed app " + name
11972                                    + " at watcher's request");
11973                            if (r != null) {
11974                                r.kill("crash", true);
11975                            } else {
11976                                // Huh.
11977                                Process.killProcess(pid);
11978                                Process.killProcessGroup(uid, pid);
11979                            }
11980                        }
11981                        return;
11982                    }
11983                } catch (RemoteException e) {
11984                    mController = null;
11985                    Watchdog.getInstance().setActivityController(null);
11986                }
11987            }
11988
11989            final long origId = Binder.clearCallingIdentity();
11990
11991            // If this process is running instrumentation, finish it.
11992            if (r != null && r.instrumentationClass != null) {
11993                Slog.w(TAG, "Error in app " + r.processName
11994                      + " running instrumentation " + r.instrumentationClass + ":");
11995                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11996                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11997                Bundle info = new Bundle();
11998                info.putString("shortMsg", shortMsg);
11999                info.putString("longMsg", longMsg);
12000                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12001                Binder.restoreCallingIdentity(origId);
12002                return;
12003            }
12004
12005            // If we can't identify the process or it's already exceeded its crash quota,
12006            // quit right away without showing a crash dialog.
12007            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12008                Binder.restoreCallingIdentity(origId);
12009                return;
12010            }
12011
12012            Message msg = Message.obtain();
12013            msg.what = SHOW_ERROR_MSG;
12014            HashMap data = new HashMap();
12015            data.put("result", result);
12016            data.put("app", r);
12017            msg.obj = data;
12018            mHandler.sendMessage(msg);
12019
12020            Binder.restoreCallingIdentity(origId);
12021        }
12022
12023        int res = result.get();
12024
12025        Intent appErrorIntent = null;
12026        synchronized (this) {
12027            if (r != null && !r.isolated) {
12028                // XXX Can't keep track of crash time for isolated processes,
12029                // since they don't have a persistent identity.
12030                mProcessCrashTimes.put(r.info.processName, r.uid,
12031                        SystemClock.uptimeMillis());
12032            }
12033            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12034                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12035            }
12036        }
12037
12038        if (appErrorIntent != null) {
12039            try {
12040                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12041            } catch (ActivityNotFoundException e) {
12042                Slog.w(TAG, "bug report receiver dissappeared", e);
12043            }
12044        }
12045    }
12046
12047    Intent createAppErrorIntentLocked(ProcessRecord r,
12048            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12049        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12050        if (report == null) {
12051            return null;
12052        }
12053        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12054        result.setComponent(r.errorReportReceiver);
12055        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12056        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12057        return result;
12058    }
12059
12060    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12061            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12062        if (r.errorReportReceiver == null) {
12063            return null;
12064        }
12065
12066        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12067            return null;
12068        }
12069
12070        ApplicationErrorReport report = new ApplicationErrorReport();
12071        report.packageName = r.info.packageName;
12072        report.installerPackageName = r.errorReportReceiver.getPackageName();
12073        report.processName = r.processName;
12074        report.time = timeMillis;
12075        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12076
12077        if (r.crashing || r.forceCrashReport) {
12078            report.type = ApplicationErrorReport.TYPE_CRASH;
12079            report.crashInfo = crashInfo;
12080        } else if (r.notResponding) {
12081            report.type = ApplicationErrorReport.TYPE_ANR;
12082            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12083
12084            report.anrInfo.activity = r.notRespondingReport.tag;
12085            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12086            report.anrInfo.info = r.notRespondingReport.longMsg;
12087        }
12088
12089        return report;
12090    }
12091
12092    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12093        enforceNotIsolatedCaller("getProcessesInErrorState");
12094        // assume our apps are happy - lazy create the list
12095        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12096
12097        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12098                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12099        int userId = UserHandle.getUserId(Binder.getCallingUid());
12100
12101        synchronized (this) {
12102
12103            // iterate across all processes
12104            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12105                ProcessRecord app = mLruProcesses.get(i);
12106                if (!allUsers && app.userId != userId) {
12107                    continue;
12108                }
12109                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12110                    // This one's in trouble, so we'll generate a report for it
12111                    // crashes are higher priority (in case there's a crash *and* an anr)
12112                    ActivityManager.ProcessErrorStateInfo report = null;
12113                    if (app.crashing) {
12114                        report = app.crashingReport;
12115                    } else if (app.notResponding) {
12116                        report = app.notRespondingReport;
12117                    }
12118
12119                    if (report != null) {
12120                        if (errList == null) {
12121                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12122                        }
12123                        errList.add(report);
12124                    } else {
12125                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12126                                " crashing = " + app.crashing +
12127                                " notResponding = " + app.notResponding);
12128                    }
12129                }
12130            }
12131        }
12132
12133        return errList;
12134    }
12135
12136    static int procStateToImportance(int procState, int memAdj,
12137            ActivityManager.RunningAppProcessInfo currApp) {
12138        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12139        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12140            currApp.lru = memAdj;
12141        } else {
12142            currApp.lru = 0;
12143        }
12144        return imp;
12145    }
12146
12147    private void fillInProcMemInfo(ProcessRecord app,
12148            ActivityManager.RunningAppProcessInfo outInfo) {
12149        outInfo.pid = app.pid;
12150        outInfo.uid = app.info.uid;
12151        if (mHeavyWeightProcess == app) {
12152            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12153        }
12154        if (app.persistent) {
12155            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12156        }
12157        if (app.activities.size() > 0) {
12158            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12159        }
12160        outInfo.lastTrimLevel = app.trimMemoryLevel;
12161        int adj = app.curAdj;
12162        int procState = app.curProcState;
12163        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12164        outInfo.importanceReasonCode = app.adjTypeCode;
12165        outInfo.processState = app.curProcState;
12166    }
12167
12168    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12169        enforceNotIsolatedCaller("getRunningAppProcesses");
12170        // Lazy instantiation of list
12171        List<ActivityManager.RunningAppProcessInfo> runList = null;
12172        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12173                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12174        int userId = UserHandle.getUserId(Binder.getCallingUid());
12175        synchronized (this) {
12176            // Iterate across all processes
12177            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12178                ProcessRecord app = mLruProcesses.get(i);
12179                if (!allUsers && app.userId != userId) {
12180                    continue;
12181                }
12182                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12183                    // Generate process state info for running application
12184                    ActivityManager.RunningAppProcessInfo currApp =
12185                        new ActivityManager.RunningAppProcessInfo(app.processName,
12186                                app.pid, app.getPackageList());
12187                    fillInProcMemInfo(app, currApp);
12188                    if (app.adjSource instanceof ProcessRecord) {
12189                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12190                        currApp.importanceReasonImportance =
12191                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12192                                        app.adjSourceProcState);
12193                    } else if (app.adjSource instanceof ActivityRecord) {
12194                        ActivityRecord r = (ActivityRecord)app.adjSource;
12195                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12196                    }
12197                    if (app.adjTarget instanceof ComponentName) {
12198                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12199                    }
12200                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12201                    //        + " lru=" + currApp.lru);
12202                    if (runList == null) {
12203                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12204                    }
12205                    runList.add(currApp);
12206                }
12207            }
12208        }
12209        return runList;
12210    }
12211
12212    public List<ApplicationInfo> getRunningExternalApplications() {
12213        enforceNotIsolatedCaller("getRunningExternalApplications");
12214        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12215        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12216        if (runningApps != null && runningApps.size() > 0) {
12217            Set<String> extList = new HashSet<String>();
12218            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12219                if (app.pkgList != null) {
12220                    for (String pkg : app.pkgList) {
12221                        extList.add(pkg);
12222                    }
12223                }
12224            }
12225            IPackageManager pm = AppGlobals.getPackageManager();
12226            for (String pkg : extList) {
12227                try {
12228                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12229                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12230                        retList.add(info);
12231                    }
12232                } catch (RemoteException e) {
12233                }
12234            }
12235        }
12236        return retList;
12237    }
12238
12239    @Override
12240    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12241        enforceNotIsolatedCaller("getMyMemoryState");
12242        synchronized (this) {
12243            ProcessRecord proc;
12244            synchronized (mPidsSelfLocked) {
12245                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12246            }
12247            fillInProcMemInfo(proc, outInfo);
12248        }
12249    }
12250
12251    @Override
12252    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12253        if (checkCallingPermission(android.Manifest.permission.DUMP)
12254                != PackageManager.PERMISSION_GRANTED) {
12255            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12256                    + Binder.getCallingPid()
12257                    + ", uid=" + Binder.getCallingUid()
12258                    + " without permission "
12259                    + android.Manifest.permission.DUMP);
12260            return;
12261        }
12262
12263        boolean dumpAll = false;
12264        boolean dumpClient = false;
12265        String dumpPackage = null;
12266
12267        int opti = 0;
12268        while (opti < args.length) {
12269            String opt = args[opti];
12270            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12271                break;
12272            }
12273            opti++;
12274            if ("-a".equals(opt)) {
12275                dumpAll = true;
12276            } else if ("-c".equals(opt)) {
12277                dumpClient = true;
12278            } else if ("-h".equals(opt)) {
12279                pw.println("Activity manager dump options:");
12280                pw.println("  [-a] [-c] [-h] [cmd] ...");
12281                pw.println("  cmd may be one of:");
12282                pw.println("    a[ctivities]: activity stack state");
12283                pw.println("    r[recents]: recent activities state");
12284                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12285                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12286                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12287                pw.println("    o[om]: out of memory management");
12288                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12289                pw.println("    provider [COMP_SPEC]: provider client-side state");
12290                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12291                pw.println("    service [COMP_SPEC]: service client-side state");
12292                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12293                pw.println("    all: dump all activities");
12294                pw.println("    top: dump the top activity");
12295                pw.println("    write: write all pending state to storage");
12296                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12297                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12298                pw.println("    a partial substring in a component name, a");
12299                pw.println("    hex object identifier.");
12300                pw.println("  -a: include all available server state.");
12301                pw.println("  -c: include client state.");
12302                return;
12303            } else {
12304                pw.println("Unknown argument: " + opt + "; use -h for help");
12305            }
12306        }
12307
12308        long origId = Binder.clearCallingIdentity();
12309        boolean more = false;
12310        // Is the caller requesting to dump a particular piece of data?
12311        if (opti < args.length) {
12312            String cmd = args[opti];
12313            opti++;
12314            if ("activities".equals(cmd) || "a".equals(cmd)) {
12315                synchronized (this) {
12316                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12317                }
12318            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12319                synchronized (this) {
12320                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12321                }
12322            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12323                String[] newArgs;
12324                String name;
12325                if (opti >= args.length) {
12326                    name = null;
12327                    newArgs = EMPTY_STRING_ARRAY;
12328                } else {
12329                    name = args[opti];
12330                    opti++;
12331                    newArgs = new String[args.length - opti];
12332                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12333                            args.length - opti);
12334                }
12335                synchronized (this) {
12336                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12337                }
12338            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12339                String[] newArgs;
12340                String name;
12341                if (opti >= args.length) {
12342                    name = null;
12343                    newArgs = EMPTY_STRING_ARRAY;
12344                } else {
12345                    name = args[opti];
12346                    opti++;
12347                    newArgs = new String[args.length - opti];
12348                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12349                            args.length - opti);
12350                }
12351                synchronized (this) {
12352                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12353                }
12354            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12355                String[] newArgs;
12356                String name;
12357                if (opti >= args.length) {
12358                    name = null;
12359                    newArgs = EMPTY_STRING_ARRAY;
12360                } else {
12361                    name = args[opti];
12362                    opti++;
12363                    newArgs = new String[args.length - opti];
12364                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12365                            args.length - opti);
12366                }
12367                synchronized (this) {
12368                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12369                }
12370            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12371                synchronized (this) {
12372                    dumpOomLocked(fd, pw, args, opti, true);
12373                }
12374            } else if ("provider".equals(cmd)) {
12375                String[] newArgs;
12376                String name;
12377                if (opti >= args.length) {
12378                    name = null;
12379                    newArgs = EMPTY_STRING_ARRAY;
12380                } else {
12381                    name = args[opti];
12382                    opti++;
12383                    newArgs = new String[args.length - opti];
12384                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12385                }
12386                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12387                    pw.println("No providers match: " + name);
12388                    pw.println("Use -h for help.");
12389                }
12390            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12391                synchronized (this) {
12392                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12393                }
12394            } else if ("service".equals(cmd)) {
12395                String[] newArgs;
12396                String name;
12397                if (opti >= args.length) {
12398                    name = null;
12399                    newArgs = EMPTY_STRING_ARRAY;
12400                } else {
12401                    name = args[opti];
12402                    opti++;
12403                    newArgs = new String[args.length - opti];
12404                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12405                            args.length - opti);
12406                }
12407                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12408                    pw.println("No services match: " + name);
12409                    pw.println("Use -h for help.");
12410                }
12411            } else if ("package".equals(cmd)) {
12412                String[] newArgs;
12413                if (opti >= args.length) {
12414                    pw.println("package: no package name specified");
12415                    pw.println("Use -h for help.");
12416                } else {
12417                    dumpPackage = args[opti];
12418                    opti++;
12419                    newArgs = new String[args.length - opti];
12420                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12421                            args.length - opti);
12422                    args = newArgs;
12423                    opti = 0;
12424                    more = true;
12425                }
12426            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12427                synchronized (this) {
12428                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12429                }
12430            } else if ("write".equals(cmd)) {
12431                mTaskPersister.flush();
12432                pw.println("All tasks persisted.");
12433                return;
12434            } else {
12435                // Dumping a single activity?
12436                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12437                    pw.println("Bad activity command, or no activities match: " + cmd);
12438                    pw.println("Use -h for help.");
12439                }
12440            }
12441            if (!more) {
12442                Binder.restoreCallingIdentity(origId);
12443                return;
12444            }
12445        }
12446
12447        // No piece of data specified, dump everything.
12448        synchronized (this) {
12449            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12450            pw.println();
12451            if (dumpAll) {
12452                pw.println("-------------------------------------------------------------------------------");
12453            }
12454            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12455            pw.println();
12456            if (dumpAll) {
12457                pw.println("-------------------------------------------------------------------------------");
12458            }
12459            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12460            pw.println();
12461            if (dumpAll) {
12462                pw.println("-------------------------------------------------------------------------------");
12463            }
12464            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12465            pw.println();
12466            if (dumpAll) {
12467                pw.println("-------------------------------------------------------------------------------");
12468            }
12469            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12470            pw.println();
12471            if (dumpAll) {
12472                pw.println("-------------------------------------------------------------------------------");
12473            }
12474            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12475            pw.println();
12476            if (dumpAll) {
12477                pw.println("-------------------------------------------------------------------------------");
12478            }
12479            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12480        }
12481        Binder.restoreCallingIdentity(origId);
12482    }
12483
12484    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12485            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12486        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12487
12488        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12489                dumpPackage);
12490        boolean needSep = printedAnything;
12491
12492        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12493                dumpPackage, needSep, "  mFocusedActivity: ");
12494        if (printed) {
12495            printedAnything = true;
12496            needSep = false;
12497        }
12498
12499        if (dumpPackage == null) {
12500            if (needSep) {
12501                pw.println();
12502            }
12503            needSep = true;
12504            printedAnything = true;
12505            mStackSupervisor.dump(pw, "  ");
12506        }
12507
12508        if (!printedAnything) {
12509            pw.println("  (nothing)");
12510        }
12511    }
12512
12513    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12514            int opti, boolean dumpAll, String dumpPackage) {
12515        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12516
12517        boolean printedAnything = false;
12518
12519        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12520            boolean printedHeader = false;
12521
12522            final int N = mRecentTasks.size();
12523            for (int i=0; i<N; i++) {
12524                TaskRecord tr = mRecentTasks.get(i);
12525                if (dumpPackage != null) {
12526                    if (tr.realActivity == null ||
12527                            !dumpPackage.equals(tr.realActivity)) {
12528                        continue;
12529                    }
12530                }
12531                if (!printedHeader) {
12532                    pw.println("  Recent tasks:");
12533                    printedHeader = true;
12534                    printedAnything = true;
12535                }
12536                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12537                        pw.println(tr);
12538                if (dumpAll) {
12539                    mRecentTasks.get(i).dump(pw, "    ");
12540                }
12541            }
12542        }
12543
12544        if (!printedAnything) {
12545            pw.println("  (nothing)");
12546        }
12547    }
12548
12549    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12550            int opti, boolean dumpAll, String dumpPackage) {
12551        boolean needSep = false;
12552        boolean printedAnything = false;
12553        int numPers = 0;
12554
12555        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12556
12557        if (dumpAll) {
12558            final int NP = mProcessNames.getMap().size();
12559            for (int ip=0; ip<NP; ip++) {
12560                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12561                final int NA = procs.size();
12562                for (int ia=0; ia<NA; ia++) {
12563                    ProcessRecord r = procs.valueAt(ia);
12564                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12565                        continue;
12566                    }
12567                    if (!needSep) {
12568                        pw.println("  All known processes:");
12569                        needSep = true;
12570                        printedAnything = true;
12571                    }
12572                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12573                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12574                        pw.print(" "); pw.println(r);
12575                    r.dump(pw, "    ");
12576                    if (r.persistent) {
12577                        numPers++;
12578                    }
12579                }
12580            }
12581        }
12582
12583        if (mIsolatedProcesses.size() > 0) {
12584            boolean printed = false;
12585            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12586                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12587                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12588                    continue;
12589                }
12590                if (!printed) {
12591                    if (needSep) {
12592                        pw.println();
12593                    }
12594                    pw.println("  Isolated process list (sorted by uid):");
12595                    printedAnything = true;
12596                    printed = true;
12597                    needSep = true;
12598                }
12599                pw.println(String.format("%sIsolated #%2d: %s",
12600                        "    ", i, r.toString()));
12601            }
12602        }
12603
12604        if (mLruProcesses.size() > 0) {
12605            if (needSep) {
12606                pw.println();
12607            }
12608            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12609                    pw.print(" total, non-act at ");
12610                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12611                    pw.print(", non-svc at ");
12612                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12613                    pw.println("):");
12614            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12615            needSep = true;
12616            printedAnything = true;
12617        }
12618
12619        if (dumpAll || dumpPackage != null) {
12620            synchronized (mPidsSelfLocked) {
12621                boolean printed = false;
12622                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12623                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12624                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12625                        continue;
12626                    }
12627                    if (!printed) {
12628                        if (needSep) pw.println();
12629                        needSep = true;
12630                        pw.println("  PID mappings:");
12631                        printed = true;
12632                        printedAnything = true;
12633                    }
12634                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12635                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12636                }
12637            }
12638        }
12639
12640        if (mForegroundProcesses.size() > 0) {
12641            synchronized (mPidsSelfLocked) {
12642                boolean printed = false;
12643                for (int i=0; i<mForegroundProcesses.size(); i++) {
12644                    ProcessRecord r = mPidsSelfLocked.get(
12645                            mForegroundProcesses.valueAt(i).pid);
12646                    if (dumpPackage != null && (r == null
12647                            || !r.pkgList.containsKey(dumpPackage))) {
12648                        continue;
12649                    }
12650                    if (!printed) {
12651                        if (needSep) pw.println();
12652                        needSep = true;
12653                        pw.println("  Foreground Processes:");
12654                        printed = true;
12655                        printedAnything = true;
12656                    }
12657                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12658                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12659                }
12660            }
12661        }
12662
12663        if (mPersistentStartingProcesses.size() > 0) {
12664            if (needSep) pw.println();
12665            needSep = true;
12666            printedAnything = true;
12667            pw.println("  Persisent processes that are starting:");
12668            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12669                    "Starting Norm", "Restarting PERS", dumpPackage);
12670        }
12671
12672        if (mRemovedProcesses.size() > 0) {
12673            if (needSep) pw.println();
12674            needSep = true;
12675            printedAnything = true;
12676            pw.println("  Processes that are being removed:");
12677            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12678                    "Removed Norm", "Removed PERS", dumpPackage);
12679        }
12680
12681        if (mProcessesOnHold.size() > 0) {
12682            if (needSep) pw.println();
12683            needSep = true;
12684            printedAnything = true;
12685            pw.println("  Processes that are on old until the system is ready:");
12686            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12687                    "OnHold Norm", "OnHold PERS", dumpPackage);
12688        }
12689
12690        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12691
12692        if (mProcessCrashTimes.getMap().size() > 0) {
12693            boolean printed = false;
12694            long now = SystemClock.uptimeMillis();
12695            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12696            final int NP = pmap.size();
12697            for (int ip=0; ip<NP; ip++) {
12698                String pname = pmap.keyAt(ip);
12699                SparseArray<Long> uids = pmap.valueAt(ip);
12700                final int N = uids.size();
12701                for (int i=0; i<N; i++) {
12702                    int puid = uids.keyAt(i);
12703                    ProcessRecord r = mProcessNames.get(pname, puid);
12704                    if (dumpPackage != null && (r == null
12705                            || !r.pkgList.containsKey(dumpPackage))) {
12706                        continue;
12707                    }
12708                    if (!printed) {
12709                        if (needSep) pw.println();
12710                        needSep = true;
12711                        pw.println("  Time since processes crashed:");
12712                        printed = true;
12713                        printedAnything = true;
12714                    }
12715                    pw.print("    Process "); pw.print(pname);
12716                            pw.print(" uid "); pw.print(puid);
12717                            pw.print(": last crashed ");
12718                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12719                            pw.println(" ago");
12720                }
12721            }
12722        }
12723
12724        if (mBadProcesses.getMap().size() > 0) {
12725            boolean printed = false;
12726            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12727            final int NP = pmap.size();
12728            for (int ip=0; ip<NP; ip++) {
12729                String pname = pmap.keyAt(ip);
12730                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12731                final int N = uids.size();
12732                for (int i=0; i<N; i++) {
12733                    int puid = uids.keyAt(i);
12734                    ProcessRecord r = mProcessNames.get(pname, puid);
12735                    if (dumpPackage != null && (r == null
12736                            || !r.pkgList.containsKey(dumpPackage))) {
12737                        continue;
12738                    }
12739                    if (!printed) {
12740                        if (needSep) pw.println();
12741                        needSep = true;
12742                        pw.println("  Bad processes:");
12743                        printedAnything = true;
12744                    }
12745                    BadProcessInfo info = uids.valueAt(i);
12746                    pw.print("    Bad process "); pw.print(pname);
12747                            pw.print(" uid "); pw.print(puid);
12748                            pw.print(": crashed at time "); pw.println(info.time);
12749                    if (info.shortMsg != null) {
12750                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12751                    }
12752                    if (info.longMsg != null) {
12753                        pw.print("      Long msg: "); pw.println(info.longMsg);
12754                    }
12755                    if (info.stack != null) {
12756                        pw.println("      Stack:");
12757                        int lastPos = 0;
12758                        for (int pos=0; pos<info.stack.length(); pos++) {
12759                            if (info.stack.charAt(pos) == '\n') {
12760                                pw.print("        ");
12761                                pw.write(info.stack, lastPos, pos-lastPos);
12762                                pw.println();
12763                                lastPos = pos+1;
12764                            }
12765                        }
12766                        if (lastPos < info.stack.length()) {
12767                            pw.print("        ");
12768                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12769                            pw.println();
12770                        }
12771                    }
12772                }
12773            }
12774        }
12775
12776        if (dumpPackage == null) {
12777            pw.println();
12778            needSep = false;
12779            pw.println("  mStartedUsers:");
12780            for (int i=0; i<mStartedUsers.size(); i++) {
12781                UserStartedState uss = mStartedUsers.valueAt(i);
12782                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12783                        pw.print(": "); uss.dump("", pw);
12784            }
12785            pw.print("  mStartedUserArray: [");
12786            for (int i=0; i<mStartedUserArray.length; i++) {
12787                if (i > 0) pw.print(", ");
12788                pw.print(mStartedUserArray[i]);
12789            }
12790            pw.println("]");
12791            pw.print("  mUserLru: [");
12792            for (int i=0; i<mUserLru.size(); i++) {
12793                if (i > 0) pw.print(", ");
12794                pw.print(mUserLru.get(i));
12795            }
12796            pw.println("]");
12797            if (dumpAll) {
12798                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12799            }
12800            synchronized (mUserProfileGroupIdsSelfLocked) {
12801                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12802                    pw.println("  mUserProfileGroupIds:");
12803                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12804                        pw.print("    User #");
12805                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12806                        pw.print(" -> profile #");
12807                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12808                    }
12809                }
12810            }
12811        }
12812        if (mHomeProcess != null && (dumpPackage == null
12813                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12814            if (needSep) {
12815                pw.println();
12816                needSep = false;
12817            }
12818            pw.println("  mHomeProcess: " + mHomeProcess);
12819        }
12820        if (mPreviousProcess != null && (dumpPackage == null
12821                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12822            if (needSep) {
12823                pw.println();
12824                needSep = false;
12825            }
12826            pw.println("  mPreviousProcess: " + mPreviousProcess);
12827        }
12828        if (dumpAll) {
12829            StringBuilder sb = new StringBuilder(128);
12830            sb.append("  mPreviousProcessVisibleTime: ");
12831            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12832            pw.println(sb);
12833        }
12834        if (mHeavyWeightProcess != null && (dumpPackage == null
12835                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12836            if (needSep) {
12837                pw.println();
12838                needSep = false;
12839            }
12840            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12841        }
12842        if (dumpPackage == null) {
12843            pw.println("  mConfiguration: " + mConfiguration);
12844        }
12845        if (dumpAll) {
12846            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12847            if (mCompatModePackages.getPackages().size() > 0) {
12848                boolean printed = false;
12849                for (Map.Entry<String, Integer> entry
12850                        : mCompatModePackages.getPackages().entrySet()) {
12851                    String pkg = entry.getKey();
12852                    int mode = entry.getValue();
12853                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12854                        continue;
12855                    }
12856                    if (!printed) {
12857                        pw.println("  mScreenCompatPackages:");
12858                        printed = true;
12859                    }
12860                    pw.print("    "); pw.print(pkg); pw.print(": ");
12861                            pw.print(mode); pw.println();
12862                }
12863            }
12864        }
12865        if (dumpPackage == null) {
12866            if (mSleeping || mWentToSleep || mLockScreenShown) {
12867                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12868                        + " mLockScreenShown " + mLockScreenShown);
12869            }
12870            if (mShuttingDown || mRunningVoice) {
12871                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12872            }
12873        }
12874        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12875                || mOrigWaitForDebugger) {
12876            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12877                    || dumpPackage.equals(mOrigDebugApp)) {
12878                if (needSep) {
12879                    pw.println();
12880                    needSep = false;
12881                }
12882                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12883                        + " mDebugTransient=" + mDebugTransient
12884                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12885            }
12886        }
12887        if (mOpenGlTraceApp != null) {
12888            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12889                if (needSep) {
12890                    pw.println();
12891                    needSep = false;
12892                }
12893                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12894            }
12895        }
12896        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12897                || mProfileFd != null) {
12898            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12899                if (needSep) {
12900                    pw.println();
12901                    needSep = false;
12902                }
12903                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12904                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12905                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12906                        + mAutoStopProfiler);
12907                pw.println("  mProfileType=" + mProfileType);
12908            }
12909        }
12910        if (dumpPackage == null) {
12911            if (mAlwaysFinishActivities || mController != null) {
12912                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12913                        + " mController=" + mController);
12914            }
12915            if (dumpAll) {
12916                pw.println("  Total persistent processes: " + numPers);
12917                pw.println("  mProcessesReady=" + mProcessesReady
12918                        + " mSystemReady=" + mSystemReady
12919                        + " mBooted=" + mBooted
12920                        + " mFactoryTest=" + mFactoryTest);
12921                pw.println("  mBooting=" + mBooting
12922                        + " mCallFinishBooting=" + mCallFinishBooting
12923                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12924                pw.print("  mLastPowerCheckRealtime=");
12925                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12926                        pw.println("");
12927                pw.print("  mLastPowerCheckUptime=");
12928                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12929                        pw.println("");
12930                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12931                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12932                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12933                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12934                        + " (" + mLruProcesses.size() + " total)"
12935                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12936                        + " mNumServiceProcs=" + mNumServiceProcs
12937                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12938                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12939                        + " mLastMemoryLevel" + mLastMemoryLevel
12940                        + " mLastNumProcesses" + mLastNumProcesses);
12941                long now = SystemClock.uptimeMillis();
12942                pw.print("  mLastIdleTime=");
12943                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12944                        pw.print(" mLowRamSinceLastIdle=");
12945                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12946                        pw.println();
12947            }
12948        }
12949
12950        if (!printedAnything) {
12951            pw.println("  (nothing)");
12952        }
12953    }
12954
12955    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12956            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12957        if (mProcessesToGc.size() > 0) {
12958            boolean printed = false;
12959            long now = SystemClock.uptimeMillis();
12960            for (int i=0; i<mProcessesToGc.size(); i++) {
12961                ProcessRecord proc = mProcessesToGc.get(i);
12962                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12963                    continue;
12964                }
12965                if (!printed) {
12966                    if (needSep) pw.println();
12967                    needSep = true;
12968                    pw.println("  Processes that are waiting to GC:");
12969                    printed = true;
12970                }
12971                pw.print("    Process "); pw.println(proc);
12972                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12973                        pw.print(", last gced=");
12974                        pw.print(now-proc.lastRequestedGc);
12975                        pw.print(" ms ago, last lowMem=");
12976                        pw.print(now-proc.lastLowMemory);
12977                        pw.println(" ms ago");
12978
12979            }
12980        }
12981        return needSep;
12982    }
12983
12984    void printOomLevel(PrintWriter pw, String name, int adj) {
12985        pw.print("    ");
12986        if (adj >= 0) {
12987            pw.print(' ');
12988            if (adj < 10) pw.print(' ');
12989        } else {
12990            if (adj > -10) pw.print(' ');
12991        }
12992        pw.print(adj);
12993        pw.print(": ");
12994        pw.print(name);
12995        pw.print(" (");
12996        pw.print(mProcessList.getMemLevel(adj)/1024);
12997        pw.println(" kB)");
12998    }
12999
13000    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13001            int opti, boolean dumpAll) {
13002        boolean needSep = false;
13003
13004        if (mLruProcesses.size() > 0) {
13005            if (needSep) pw.println();
13006            needSep = true;
13007            pw.println("  OOM levels:");
13008            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13009            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13010            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13011            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13012            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13013            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13014            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13015            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13016            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13017            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13018            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13019            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13020            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13021
13022            if (needSep) pw.println();
13023            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13024                    pw.print(" total, non-act at ");
13025                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13026                    pw.print(", non-svc at ");
13027                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13028                    pw.println("):");
13029            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13030            needSep = true;
13031        }
13032
13033        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13034
13035        pw.println();
13036        pw.println("  mHomeProcess: " + mHomeProcess);
13037        pw.println("  mPreviousProcess: " + mPreviousProcess);
13038        if (mHeavyWeightProcess != null) {
13039            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13040        }
13041
13042        return true;
13043    }
13044
13045    /**
13046     * There are three ways to call this:
13047     *  - no provider specified: dump all the providers
13048     *  - a flattened component name that matched an existing provider was specified as the
13049     *    first arg: dump that one provider
13050     *  - the first arg isn't the flattened component name of an existing provider:
13051     *    dump all providers whose component contains the first arg as a substring
13052     */
13053    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13054            int opti, boolean dumpAll) {
13055        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13056    }
13057
13058    static class ItemMatcher {
13059        ArrayList<ComponentName> components;
13060        ArrayList<String> strings;
13061        ArrayList<Integer> objects;
13062        boolean all;
13063
13064        ItemMatcher() {
13065            all = true;
13066        }
13067
13068        void build(String name) {
13069            ComponentName componentName = ComponentName.unflattenFromString(name);
13070            if (componentName != null) {
13071                if (components == null) {
13072                    components = new ArrayList<ComponentName>();
13073                }
13074                components.add(componentName);
13075                all = false;
13076            } else {
13077                int objectId = 0;
13078                // Not a '/' separated full component name; maybe an object ID?
13079                try {
13080                    objectId = Integer.parseInt(name, 16);
13081                    if (objects == null) {
13082                        objects = new ArrayList<Integer>();
13083                    }
13084                    objects.add(objectId);
13085                    all = false;
13086                } catch (RuntimeException e) {
13087                    // Not an integer; just do string match.
13088                    if (strings == null) {
13089                        strings = new ArrayList<String>();
13090                    }
13091                    strings.add(name);
13092                    all = false;
13093                }
13094            }
13095        }
13096
13097        int build(String[] args, int opti) {
13098            for (; opti<args.length; opti++) {
13099                String name = args[opti];
13100                if ("--".equals(name)) {
13101                    return opti+1;
13102                }
13103                build(name);
13104            }
13105            return opti;
13106        }
13107
13108        boolean match(Object object, ComponentName comp) {
13109            if (all) {
13110                return true;
13111            }
13112            if (components != null) {
13113                for (int i=0; i<components.size(); i++) {
13114                    if (components.get(i).equals(comp)) {
13115                        return true;
13116                    }
13117                }
13118            }
13119            if (objects != null) {
13120                for (int i=0; i<objects.size(); i++) {
13121                    if (System.identityHashCode(object) == objects.get(i)) {
13122                        return true;
13123                    }
13124                }
13125            }
13126            if (strings != null) {
13127                String flat = comp.flattenToString();
13128                for (int i=0; i<strings.size(); i++) {
13129                    if (flat.contains(strings.get(i))) {
13130                        return true;
13131                    }
13132                }
13133            }
13134            return false;
13135        }
13136    }
13137
13138    /**
13139     * There are three things that cmd can be:
13140     *  - a flattened component name that matches an existing activity
13141     *  - the cmd arg isn't the flattened component name of an existing activity:
13142     *    dump all activity whose component contains the cmd as a substring
13143     *  - A hex number of the ActivityRecord object instance.
13144     */
13145    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13146            int opti, boolean dumpAll) {
13147        ArrayList<ActivityRecord> activities;
13148
13149        synchronized (this) {
13150            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13151        }
13152
13153        if (activities.size() <= 0) {
13154            return false;
13155        }
13156
13157        String[] newArgs = new String[args.length - opti];
13158        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13159
13160        TaskRecord lastTask = null;
13161        boolean needSep = false;
13162        for (int i=activities.size()-1; i>=0; i--) {
13163            ActivityRecord r = activities.get(i);
13164            if (needSep) {
13165                pw.println();
13166            }
13167            needSep = true;
13168            synchronized (this) {
13169                if (lastTask != r.task) {
13170                    lastTask = r.task;
13171                    pw.print("TASK "); pw.print(lastTask.affinity);
13172                            pw.print(" id="); pw.println(lastTask.taskId);
13173                    if (dumpAll) {
13174                        lastTask.dump(pw, "  ");
13175                    }
13176                }
13177            }
13178            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13179        }
13180        return true;
13181    }
13182
13183    /**
13184     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13185     * there is a thread associated with the activity.
13186     */
13187    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13188            final ActivityRecord r, String[] args, boolean dumpAll) {
13189        String innerPrefix = prefix + "  ";
13190        synchronized (this) {
13191            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13192                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13193                    pw.print(" pid=");
13194                    if (r.app != null) pw.println(r.app.pid);
13195                    else pw.println("(not running)");
13196            if (dumpAll) {
13197                r.dump(pw, innerPrefix);
13198            }
13199        }
13200        if (r.app != null && r.app.thread != null) {
13201            // flush anything that is already in the PrintWriter since the thread is going
13202            // to write to the file descriptor directly
13203            pw.flush();
13204            try {
13205                TransferPipe tp = new TransferPipe();
13206                try {
13207                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13208                            r.appToken, innerPrefix, args);
13209                    tp.go(fd);
13210                } finally {
13211                    tp.kill();
13212                }
13213            } catch (IOException e) {
13214                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13215            } catch (RemoteException e) {
13216                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13217            }
13218        }
13219    }
13220
13221    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13222            int opti, boolean dumpAll, String dumpPackage) {
13223        boolean needSep = false;
13224        boolean onlyHistory = false;
13225        boolean printedAnything = false;
13226
13227        if ("history".equals(dumpPackage)) {
13228            if (opti < args.length && "-s".equals(args[opti])) {
13229                dumpAll = false;
13230            }
13231            onlyHistory = true;
13232            dumpPackage = null;
13233        }
13234
13235        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13236        if (!onlyHistory && dumpAll) {
13237            if (mRegisteredReceivers.size() > 0) {
13238                boolean printed = false;
13239                Iterator it = mRegisteredReceivers.values().iterator();
13240                while (it.hasNext()) {
13241                    ReceiverList r = (ReceiverList)it.next();
13242                    if (dumpPackage != null && (r.app == null ||
13243                            !dumpPackage.equals(r.app.info.packageName))) {
13244                        continue;
13245                    }
13246                    if (!printed) {
13247                        pw.println("  Registered Receivers:");
13248                        needSep = true;
13249                        printed = true;
13250                        printedAnything = true;
13251                    }
13252                    pw.print("  * "); pw.println(r);
13253                    r.dump(pw, "    ");
13254                }
13255            }
13256
13257            if (mReceiverResolver.dump(pw, needSep ?
13258                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13259                    "    ", dumpPackage, false)) {
13260                needSep = true;
13261                printedAnything = true;
13262            }
13263        }
13264
13265        for (BroadcastQueue q : mBroadcastQueues) {
13266            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13267            printedAnything |= needSep;
13268        }
13269
13270        needSep = true;
13271
13272        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13273            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13274                if (needSep) {
13275                    pw.println();
13276                }
13277                needSep = true;
13278                printedAnything = true;
13279                pw.print("  Sticky broadcasts for user ");
13280                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13281                StringBuilder sb = new StringBuilder(128);
13282                for (Map.Entry<String, ArrayList<Intent>> ent
13283                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13284                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13285                    if (dumpAll) {
13286                        pw.println(":");
13287                        ArrayList<Intent> intents = ent.getValue();
13288                        final int N = intents.size();
13289                        for (int i=0; i<N; i++) {
13290                            sb.setLength(0);
13291                            sb.append("    Intent: ");
13292                            intents.get(i).toShortString(sb, false, true, false, false);
13293                            pw.println(sb.toString());
13294                            Bundle bundle = intents.get(i).getExtras();
13295                            if (bundle != null) {
13296                                pw.print("      ");
13297                                pw.println(bundle.toString());
13298                            }
13299                        }
13300                    } else {
13301                        pw.println("");
13302                    }
13303                }
13304            }
13305        }
13306
13307        if (!onlyHistory && dumpAll) {
13308            pw.println();
13309            for (BroadcastQueue queue : mBroadcastQueues) {
13310                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13311                        + queue.mBroadcastsScheduled);
13312            }
13313            pw.println("  mHandler:");
13314            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13315            needSep = true;
13316            printedAnything = true;
13317        }
13318
13319        if (!printedAnything) {
13320            pw.println("  (nothing)");
13321        }
13322    }
13323
13324    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13325            int opti, boolean dumpAll, String dumpPackage) {
13326        boolean needSep;
13327        boolean printedAnything = false;
13328
13329        ItemMatcher matcher = new ItemMatcher();
13330        matcher.build(args, opti);
13331
13332        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13333
13334        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13335        printedAnything |= needSep;
13336
13337        if (mLaunchingProviders.size() > 0) {
13338            boolean printed = false;
13339            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13340                ContentProviderRecord r = mLaunchingProviders.get(i);
13341                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13342                    continue;
13343                }
13344                if (!printed) {
13345                    if (needSep) pw.println();
13346                    needSep = true;
13347                    pw.println("  Launching content providers:");
13348                    printed = true;
13349                    printedAnything = true;
13350                }
13351                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13352                        pw.println(r);
13353            }
13354        }
13355
13356        if (mGrantedUriPermissions.size() > 0) {
13357            boolean printed = false;
13358            int dumpUid = -2;
13359            if (dumpPackage != null) {
13360                try {
13361                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13362                } catch (NameNotFoundException e) {
13363                    dumpUid = -1;
13364                }
13365            }
13366            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13367                int uid = mGrantedUriPermissions.keyAt(i);
13368                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13369                    continue;
13370                }
13371                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13372                if (!printed) {
13373                    if (needSep) pw.println();
13374                    needSep = true;
13375                    pw.println("  Granted Uri Permissions:");
13376                    printed = true;
13377                    printedAnything = true;
13378                }
13379                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13380                for (UriPermission perm : perms.values()) {
13381                    pw.print("    "); pw.println(perm);
13382                    if (dumpAll) {
13383                        perm.dump(pw, "      ");
13384                    }
13385                }
13386            }
13387        }
13388
13389        if (!printedAnything) {
13390            pw.println("  (nothing)");
13391        }
13392    }
13393
13394    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13395            int opti, boolean dumpAll, String dumpPackage) {
13396        boolean printed = false;
13397
13398        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13399
13400        if (mIntentSenderRecords.size() > 0) {
13401            Iterator<WeakReference<PendingIntentRecord>> it
13402                    = mIntentSenderRecords.values().iterator();
13403            while (it.hasNext()) {
13404                WeakReference<PendingIntentRecord> ref = it.next();
13405                PendingIntentRecord rec = ref != null ? ref.get(): null;
13406                if (dumpPackage != null && (rec == null
13407                        || !dumpPackage.equals(rec.key.packageName))) {
13408                    continue;
13409                }
13410                printed = true;
13411                if (rec != null) {
13412                    pw.print("  * "); pw.println(rec);
13413                    if (dumpAll) {
13414                        rec.dump(pw, "    ");
13415                    }
13416                } else {
13417                    pw.print("  * "); pw.println(ref);
13418                }
13419            }
13420        }
13421
13422        if (!printed) {
13423            pw.println("  (nothing)");
13424        }
13425    }
13426
13427    private static final int dumpProcessList(PrintWriter pw,
13428            ActivityManagerService service, List list,
13429            String prefix, String normalLabel, String persistentLabel,
13430            String dumpPackage) {
13431        int numPers = 0;
13432        final int N = list.size()-1;
13433        for (int i=N; i>=0; i--) {
13434            ProcessRecord r = (ProcessRecord)list.get(i);
13435            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13436                continue;
13437            }
13438            pw.println(String.format("%s%s #%2d: %s",
13439                    prefix, (r.persistent ? persistentLabel : normalLabel),
13440                    i, r.toString()));
13441            if (r.persistent) {
13442                numPers++;
13443            }
13444        }
13445        return numPers;
13446    }
13447
13448    private static final boolean dumpProcessOomList(PrintWriter pw,
13449            ActivityManagerService service, List<ProcessRecord> origList,
13450            String prefix, String normalLabel, String persistentLabel,
13451            boolean inclDetails, String dumpPackage) {
13452
13453        ArrayList<Pair<ProcessRecord, Integer>> list
13454                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13455        for (int i=0; i<origList.size(); i++) {
13456            ProcessRecord r = origList.get(i);
13457            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13458                continue;
13459            }
13460            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13461        }
13462
13463        if (list.size() <= 0) {
13464            return false;
13465        }
13466
13467        Comparator<Pair<ProcessRecord, Integer>> comparator
13468                = new Comparator<Pair<ProcessRecord, Integer>>() {
13469            @Override
13470            public int compare(Pair<ProcessRecord, Integer> object1,
13471                    Pair<ProcessRecord, Integer> object2) {
13472                if (object1.first.setAdj != object2.first.setAdj) {
13473                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13474                }
13475                if (object1.second.intValue() != object2.second.intValue()) {
13476                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13477                }
13478                return 0;
13479            }
13480        };
13481
13482        Collections.sort(list, comparator);
13483
13484        final long curRealtime = SystemClock.elapsedRealtime();
13485        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13486        final long curUptime = SystemClock.uptimeMillis();
13487        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13488
13489        for (int i=list.size()-1; i>=0; i--) {
13490            ProcessRecord r = list.get(i).first;
13491            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13492            char schedGroup;
13493            switch (r.setSchedGroup) {
13494                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13495                    schedGroup = 'B';
13496                    break;
13497                case Process.THREAD_GROUP_DEFAULT:
13498                    schedGroup = 'F';
13499                    break;
13500                default:
13501                    schedGroup = '?';
13502                    break;
13503            }
13504            char foreground;
13505            if (r.foregroundActivities) {
13506                foreground = 'A';
13507            } else if (r.foregroundServices) {
13508                foreground = 'S';
13509            } else {
13510                foreground = ' ';
13511            }
13512            String procState = ProcessList.makeProcStateString(r.curProcState);
13513            pw.print(prefix);
13514            pw.print(r.persistent ? persistentLabel : normalLabel);
13515            pw.print(" #");
13516            int num = (origList.size()-1)-list.get(i).second;
13517            if (num < 10) pw.print(' ');
13518            pw.print(num);
13519            pw.print(": ");
13520            pw.print(oomAdj);
13521            pw.print(' ');
13522            pw.print(schedGroup);
13523            pw.print('/');
13524            pw.print(foreground);
13525            pw.print('/');
13526            pw.print(procState);
13527            pw.print(" trm:");
13528            if (r.trimMemoryLevel < 10) pw.print(' ');
13529            pw.print(r.trimMemoryLevel);
13530            pw.print(' ');
13531            pw.print(r.toShortString());
13532            pw.print(" (");
13533            pw.print(r.adjType);
13534            pw.println(')');
13535            if (r.adjSource != null || r.adjTarget != null) {
13536                pw.print(prefix);
13537                pw.print("    ");
13538                if (r.adjTarget instanceof ComponentName) {
13539                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13540                } else if (r.adjTarget != null) {
13541                    pw.print(r.adjTarget.toString());
13542                } else {
13543                    pw.print("{null}");
13544                }
13545                pw.print("<=");
13546                if (r.adjSource instanceof ProcessRecord) {
13547                    pw.print("Proc{");
13548                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13549                    pw.println("}");
13550                } else if (r.adjSource != null) {
13551                    pw.println(r.adjSource.toString());
13552                } else {
13553                    pw.println("{null}");
13554                }
13555            }
13556            if (inclDetails) {
13557                pw.print(prefix);
13558                pw.print("    ");
13559                pw.print("oom: max="); pw.print(r.maxAdj);
13560                pw.print(" curRaw="); pw.print(r.curRawAdj);
13561                pw.print(" setRaw="); pw.print(r.setRawAdj);
13562                pw.print(" cur="); pw.print(r.curAdj);
13563                pw.print(" set="); pw.println(r.setAdj);
13564                pw.print(prefix);
13565                pw.print("    ");
13566                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13567                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13568                pw.print(" lastPss="); pw.print(r.lastPss);
13569                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13570                pw.print(prefix);
13571                pw.print("    ");
13572                pw.print("cached="); pw.print(r.cached);
13573                pw.print(" empty="); pw.print(r.empty);
13574                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13575
13576                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13577                    if (r.lastWakeTime != 0) {
13578                        long wtime;
13579                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13580                        synchronized (stats) {
13581                            wtime = stats.getProcessWakeTime(r.info.uid,
13582                                    r.pid, curRealtime);
13583                        }
13584                        long timeUsed = wtime - r.lastWakeTime;
13585                        pw.print(prefix);
13586                        pw.print("    ");
13587                        pw.print("keep awake over ");
13588                        TimeUtils.formatDuration(realtimeSince, pw);
13589                        pw.print(" used ");
13590                        TimeUtils.formatDuration(timeUsed, pw);
13591                        pw.print(" (");
13592                        pw.print((timeUsed*100)/realtimeSince);
13593                        pw.println("%)");
13594                    }
13595                    if (r.lastCpuTime != 0) {
13596                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13597                        pw.print(prefix);
13598                        pw.print("    ");
13599                        pw.print("run cpu over ");
13600                        TimeUtils.formatDuration(uptimeSince, pw);
13601                        pw.print(" used ");
13602                        TimeUtils.formatDuration(timeUsed, pw);
13603                        pw.print(" (");
13604                        pw.print((timeUsed*100)/uptimeSince);
13605                        pw.println("%)");
13606                    }
13607                }
13608            }
13609        }
13610        return true;
13611    }
13612
13613    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13614        ArrayList<ProcessRecord> procs;
13615        synchronized (this) {
13616            if (args != null && args.length > start
13617                    && args[start].charAt(0) != '-') {
13618                procs = new ArrayList<ProcessRecord>();
13619                int pid = -1;
13620                try {
13621                    pid = Integer.parseInt(args[start]);
13622                } catch (NumberFormatException e) {
13623                }
13624                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13625                    ProcessRecord proc = mLruProcesses.get(i);
13626                    if (proc.pid == pid) {
13627                        procs.add(proc);
13628                    } else if (proc.processName.equals(args[start])) {
13629                        procs.add(proc);
13630                    }
13631                }
13632                if (procs.size() <= 0) {
13633                    return null;
13634                }
13635            } else {
13636                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13637            }
13638        }
13639        return procs;
13640    }
13641
13642    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13643            PrintWriter pw, String[] args) {
13644        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13645        if (procs == null) {
13646            pw.println("No process found for: " + args[0]);
13647            return;
13648        }
13649
13650        long uptime = SystemClock.uptimeMillis();
13651        long realtime = SystemClock.elapsedRealtime();
13652        pw.println("Applications Graphics Acceleration Info:");
13653        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13654
13655        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13656            ProcessRecord r = procs.get(i);
13657            if (r.thread != null) {
13658                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13659                pw.flush();
13660                try {
13661                    TransferPipe tp = new TransferPipe();
13662                    try {
13663                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13664                        tp.go(fd);
13665                    } finally {
13666                        tp.kill();
13667                    }
13668                } catch (IOException e) {
13669                    pw.println("Failure while dumping the app: " + r);
13670                    pw.flush();
13671                } catch (RemoteException e) {
13672                    pw.println("Got a RemoteException while dumping the app " + r);
13673                    pw.flush();
13674                }
13675            }
13676        }
13677    }
13678
13679    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13680        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13681        if (procs == null) {
13682            pw.println("No process found for: " + args[0]);
13683            return;
13684        }
13685
13686        pw.println("Applications Database Info:");
13687
13688        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13689            ProcessRecord r = procs.get(i);
13690            if (r.thread != null) {
13691                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13692                pw.flush();
13693                try {
13694                    TransferPipe tp = new TransferPipe();
13695                    try {
13696                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13697                        tp.go(fd);
13698                    } finally {
13699                        tp.kill();
13700                    }
13701                } catch (IOException e) {
13702                    pw.println("Failure while dumping the app: " + r);
13703                    pw.flush();
13704                } catch (RemoteException e) {
13705                    pw.println("Got a RemoteException while dumping the app " + r);
13706                    pw.flush();
13707                }
13708            }
13709        }
13710    }
13711
13712    final static class MemItem {
13713        final boolean isProc;
13714        final String label;
13715        final String shortLabel;
13716        final long pss;
13717        final int id;
13718        final boolean hasActivities;
13719        ArrayList<MemItem> subitems;
13720
13721        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13722                boolean _hasActivities) {
13723            isProc = true;
13724            label = _label;
13725            shortLabel = _shortLabel;
13726            pss = _pss;
13727            id = _id;
13728            hasActivities = _hasActivities;
13729        }
13730
13731        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13732            isProc = false;
13733            label = _label;
13734            shortLabel = _shortLabel;
13735            pss = _pss;
13736            id = _id;
13737            hasActivities = false;
13738        }
13739    }
13740
13741    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13742            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13743        if (sort && !isCompact) {
13744            Collections.sort(items, new Comparator<MemItem>() {
13745                @Override
13746                public int compare(MemItem lhs, MemItem rhs) {
13747                    if (lhs.pss < rhs.pss) {
13748                        return 1;
13749                    } else if (lhs.pss > rhs.pss) {
13750                        return -1;
13751                    }
13752                    return 0;
13753                }
13754            });
13755        }
13756
13757        for (int i=0; i<items.size(); i++) {
13758            MemItem mi = items.get(i);
13759            if (!isCompact) {
13760                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13761            } else if (mi.isProc) {
13762                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13763                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13764                pw.println(mi.hasActivities ? ",a" : ",e");
13765            } else {
13766                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13767                pw.println(mi.pss);
13768            }
13769            if (mi.subitems != null) {
13770                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13771                        true, isCompact);
13772            }
13773        }
13774    }
13775
13776    // These are in KB.
13777    static final long[] DUMP_MEM_BUCKETS = new long[] {
13778        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13779        120*1024, 160*1024, 200*1024,
13780        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13781        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13782    };
13783
13784    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13785            boolean stackLike) {
13786        int start = label.lastIndexOf('.');
13787        if (start >= 0) start++;
13788        else start = 0;
13789        int end = label.length();
13790        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13791            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13792                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13793                out.append(bucket);
13794                out.append(stackLike ? "MB." : "MB ");
13795                out.append(label, start, end);
13796                return;
13797            }
13798        }
13799        out.append(memKB/1024);
13800        out.append(stackLike ? "MB." : "MB ");
13801        out.append(label, start, end);
13802    }
13803
13804    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13805            ProcessList.NATIVE_ADJ,
13806            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13807            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13808            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13809            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13810            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13811    };
13812    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13813            "Native",
13814            "System", "Persistent", "Foreground",
13815            "Visible", "Perceptible",
13816            "Heavy Weight", "Backup",
13817            "A Services", "Home",
13818            "Previous", "B Services", "Cached"
13819    };
13820    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13821            "native",
13822            "sys", "pers", "fore",
13823            "vis", "percept",
13824            "heavy", "backup",
13825            "servicea", "home",
13826            "prev", "serviceb", "cached"
13827    };
13828
13829    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13830            long realtime, boolean isCheckinRequest, boolean isCompact) {
13831        if (isCheckinRequest || isCompact) {
13832            // short checkin version
13833            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13834        } else {
13835            pw.println("Applications Memory Usage (kB):");
13836            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13837        }
13838    }
13839
13840    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13841            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13842        boolean dumpDetails = false;
13843        boolean dumpFullDetails = false;
13844        boolean dumpDalvik = false;
13845        boolean oomOnly = false;
13846        boolean isCompact = false;
13847        boolean localOnly = false;
13848
13849        int opti = 0;
13850        while (opti < args.length) {
13851            String opt = args[opti];
13852            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13853                break;
13854            }
13855            opti++;
13856            if ("-a".equals(opt)) {
13857                dumpDetails = true;
13858                dumpFullDetails = true;
13859                dumpDalvik = true;
13860            } else if ("-d".equals(opt)) {
13861                dumpDalvik = true;
13862            } else if ("-c".equals(opt)) {
13863                isCompact = true;
13864            } else if ("--oom".equals(opt)) {
13865                oomOnly = true;
13866            } else if ("--local".equals(opt)) {
13867                localOnly = true;
13868            } else if ("-h".equals(opt)) {
13869                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13870                pw.println("  -a: include all available information for each process.");
13871                pw.println("  -d: include dalvik details when dumping process details.");
13872                pw.println("  -c: dump in a compact machine-parseable representation.");
13873                pw.println("  --oom: only show processes organized by oom adj.");
13874                pw.println("  --local: only collect details locally, don't call process.");
13875                pw.println("If [process] is specified it can be the name or ");
13876                pw.println("pid of a specific process to dump.");
13877                return;
13878            } else {
13879                pw.println("Unknown argument: " + opt + "; use -h for help");
13880            }
13881        }
13882
13883        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13884        long uptime = SystemClock.uptimeMillis();
13885        long realtime = SystemClock.elapsedRealtime();
13886        final long[] tmpLong = new long[1];
13887
13888        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13889        if (procs == null) {
13890            // No Java processes.  Maybe they want to print a native process.
13891            if (args != null && args.length > opti
13892                    && args[opti].charAt(0) != '-') {
13893                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13894                        = new ArrayList<ProcessCpuTracker.Stats>();
13895                updateCpuStatsNow();
13896                int findPid = -1;
13897                try {
13898                    findPid = Integer.parseInt(args[opti]);
13899                } catch (NumberFormatException e) {
13900                }
13901                synchronized (mProcessCpuTracker) {
13902                    final int N = mProcessCpuTracker.countStats();
13903                    for (int i=0; i<N; i++) {
13904                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13905                        if (st.pid == findPid || (st.baseName != null
13906                                && st.baseName.equals(args[opti]))) {
13907                            nativeProcs.add(st);
13908                        }
13909                    }
13910                }
13911                if (nativeProcs.size() > 0) {
13912                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13913                            isCompact);
13914                    Debug.MemoryInfo mi = null;
13915                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13916                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13917                        final int pid = r.pid;
13918                        if (!isCheckinRequest && dumpDetails) {
13919                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13920                        }
13921                        if (mi == null) {
13922                            mi = new Debug.MemoryInfo();
13923                        }
13924                        if (dumpDetails || (!brief && !oomOnly)) {
13925                            Debug.getMemoryInfo(pid, mi);
13926                        } else {
13927                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13928                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13929                        }
13930                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13931                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13932                        if (isCheckinRequest) {
13933                            pw.println();
13934                        }
13935                    }
13936                    return;
13937                }
13938            }
13939            pw.println("No process found for: " + args[opti]);
13940            return;
13941        }
13942
13943        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13944            dumpDetails = true;
13945        }
13946
13947        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13948
13949        String[] innerArgs = new String[args.length-opti];
13950        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13951
13952        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13953        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13954        long nativePss=0, dalvikPss=0, otherPss=0;
13955        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13956
13957        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13958        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13959                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13960
13961        long totalPss = 0;
13962        long cachedPss = 0;
13963
13964        Debug.MemoryInfo mi = null;
13965        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13966            final ProcessRecord r = procs.get(i);
13967            final IApplicationThread thread;
13968            final int pid;
13969            final int oomAdj;
13970            final boolean hasActivities;
13971            synchronized (this) {
13972                thread = r.thread;
13973                pid = r.pid;
13974                oomAdj = r.getSetAdjWithServices();
13975                hasActivities = r.activities.size() > 0;
13976            }
13977            if (thread != null) {
13978                if (!isCheckinRequest && dumpDetails) {
13979                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13980                }
13981                if (mi == null) {
13982                    mi = new Debug.MemoryInfo();
13983                }
13984                if (dumpDetails || (!brief && !oomOnly)) {
13985                    Debug.getMemoryInfo(pid, mi);
13986                } else {
13987                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13988                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13989                }
13990                if (dumpDetails) {
13991                    if (localOnly) {
13992                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13993                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13994                        if (isCheckinRequest) {
13995                            pw.println();
13996                        }
13997                    } else {
13998                        try {
13999                            pw.flush();
14000                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14001                                    dumpDalvik, innerArgs);
14002                        } catch (RemoteException e) {
14003                            if (!isCheckinRequest) {
14004                                pw.println("Got RemoteException!");
14005                                pw.flush();
14006                            }
14007                        }
14008                    }
14009                }
14010
14011                final long myTotalPss = mi.getTotalPss();
14012                final long myTotalUss = mi.getTotalUss();
14013
14014                synchronized (this) {
14015                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14016                        // Record this for posterity if the process has been stable.
14017                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14018                    }
14019                }
14020
14021                if (!isCheckinRequest && mi != null) {
14022                    totalPss += myTotalPss;
14023                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14024                            (hasActivities ? " / activities)" : ")"),
14025                            r.processName, myTotalPss, pid, hasActivities);
14026                    procMems.add(pssItem);
14027                    procMemsMap.put(pid, pssItem);
14028
14029                    nativePss += mi.nativePss;
14030                    dalvikPss += mi.dalvikPss;
14031                    otherPss += mi.otherPss;
14032                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14033                        long mem = mi.getOtherPss(j);
14034                        miscPss[j] += mem;
14035                        otherPss -= mem;
14036                    }
14037
14038                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14039                        cachedPss += myTotalPss;
14040                    }
14041
14042                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14043                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14044                                || oomIndex == (oomPss.length-1)) {
14045                            oomPss[oomIndex] += myTotalPss;
14046                            if (oomProcs[oomIndex] == null) {
14047                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14048                            }
14049                            oomProcs[oomIndex].add(pssItem);
14050                            break;
14051                        }
14052                    }
14053                }
14054            }
14055        }
14056
14057        long nativeProcTotalPss = 0;
14058
14059        if (!isCheckinRequest && procs.size() > 1) {
14060            // If we are showing aggregations, also look for native processes to
14061            // include so that our aggregations are more accurate.
14062            updateCpuStatsNow();
14063            synchronized (mProcessCpuTracker) {
14064                final int N = mProcessCpuTracker.countStats();
14065                for (int i=0; i<N; i++) {
14066                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14067                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14068                        if (mi == null) {
14069                            mi = new Debug.MemoryInfo();
14070                        }
14071                        if (!brief && !oomOnly) {
14072                            Debug.getMemoryInfo(st.pid, mi);
14073                        } else {
14074                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14075                            mi.nativePrivateDirty = (int)tmpLong[0];
14076                        }
14077
14078                        final long myTotalPss = mi.getTotalPss();
14079                        totalPss += myTotalPss;
14080                        nativeProcTotalPss += myTotalPss;
14081
14082                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14083                                st.name, myTotalPss, st.pid, false);
14084                        procMems.add(pssItem);
14085
14086                        nativePss += mi.nativePss;
14087                        dalvikPss += mi.dalvikPss;
14088                        otherPss += mi.otherPss;
14089                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14090                            long mem = mi.getOtherPss(j);
14091                            miscPss[j] += mem;
14092                            otherPss -= mem;
14093                        }
14094                        oomPss[0] += myTotalPss;
14095                        if (oomProcs[0] == null) {
14096                            oomProcs[0] = new ArrayList<MemItem>();
14097                        }
14098                        oomProcs[0].add(pssItem);
14099                    }
14100                }
14101            }
14102
14103            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14104
14105            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14106            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14107            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14108            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14109                String label = Debug.MemoryInfo.getOtherLabel(j);
14110                catMems.add(new MemItem(label, label, miscPss[j], j));
14111            }
14112
14113            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14114            for (int j=0; j<oomPss.length; j++) {
14115                if (oomPss[j] != 0) {
14116                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14117                            : DUMP_MEM_OOM_LABEL[j];
14118                    MemItem item = new MemItem(label, label, oomPss[j],
14119                            DUMP_MEM_OOM_ADJ[j]);
14120                    item.subitems = oomProcs[j];
14121                    oomMems.add(item);
14122                }
14123            }
14124
14125            if (!brief && !oomOnly && !isCompact) {
14126                pw.println();
14127                pw.println("Total PSS by process:");
14128                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14129                pw.println();
14130            }
14131            if (!isCompact) {
14132                pw.println("Total PSS by OOM adjustment:");
14133            }
14134            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14135            if (!brief && !oomOnly) {
14136                PrintWriter out = categoryPw != null ? categoryPw : pw;
14137                if (!isCompact) {
14138                    out.println();
14139                    out.println("Total PSS by category:");
14140                }
14141                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14142            }
14143            if (!isCompact) {
14144                pw.println();
14145            }
14146            MemInfoReader memInfo = new MemInfoReader();
14147            memInfo.readMemInfo();
14148            if (nativeProcTotalPss > 0) {
14149                synchronized (this) {
14150                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14151                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14152                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14153                            nativeProcTotalPss);
14154                }
14155            }
14156            if (!brief) {
14157                if (!isCompact) {
14158                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14159                    pw.print(" kB (status ");
14160                    switch (mLastMemoryLevel) {
14161                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14162                            pw.println("normal)");
14163                            break;
14164                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14165                            pw.println("moderate)");
14166                            break;
14167                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14168                            pw.println("low)");
14169                            break;
14170                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14171                            pw.println("critical)");
14172                            break;
14173                        default:
14174                            pw.print(mLastMemoryLevel);
14175                            pw.println(")");
14176                            break;
14177                    }
14178                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14179                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14180                            pw.print(cachedPss); pw.print(" cached pss + ");
14181                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14182                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14183                } else {
14184                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14185                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14186                            + memInfo.getFreeSizeKb()); pw.print(",");
14187                    pw.println(totalPss - cachedPss);
14188                }
14189            }
14190            if (!isCompact) {
14191                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14192                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14193                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14194                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14195                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14196                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14197                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14198                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14199                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14200                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14201                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14202            }
14203            if (!brief) {
14204                if (memInfo.getZramTotalSizeKb() != 0) {
14205                    if (!isCompact) {
14206                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14207                                pw.print(" kB physical used for ");
14208                                pw.print(memInfo.getSwapTotalSizeKb()
14209                                        - memInfo.getSwapFreeSizeKb());
14210                                pw.print(" kB in swap (");
14211                                pw.print(memInfo.getSwapTotalSizeKb());
14212                                pw.println(" kB total swap)");
14213                    } else {
14214                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14215                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14216                                pw.println(memInfo.getSwapFreeSizeKb());
14217                    }
14218                }
14219                final int[] SINGLE_LONG_FORMAT = new int[] {
14220                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14221                };
14222                long[] longOut = new long[1];
14223                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14224                        SINGLE_LONG_FORMAT, null, longOut, null);
14225                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14226                longOut[0] = 0;
14227                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14228                        SINGLE_LONG_FORMAT, null, longOut, null);
14229                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14230                longOut[0] = 0;
14231                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14232                        SINGLE_LONG_FORMAT, null, longOut, null);
14233                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14234                longOut[0] = 0;
14235                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14236                        SINGLE_LONG_FORMAT, null, longOut, null);
14237                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14238                if (!isCompact) {
14239                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14240                        pw.print("      KSM: "); pw.print(sharing);
14241                                pw.print(" kB saved from shared ");
14242                                pw.print(shared); pw.println(" kB");
14243                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14244                                pw.print(voltile); pw.println(" kB volatile");
14245                    }
14246                    pw.print("   Tuning: ");
14247                    pw.print(ActivityManager.staticGetMemoryClass());
14248                    pw.print(" (large ");
14249                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14250                    pw.print("), oom ");
14251                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14252                    pw.print(" kB");
14253                    pw.print(", restore limit ");
14254                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14255                    pw.print(" kB");
14256                    if (ActivityManager.isLowRamDeviceStatic()) {
14257                        pw.print(" (low-ram)");
14258                    }
14259                    if (ActivityManager.isHighEndGfx()) {
14260                        pw.print(" (high-end-gfx)");
14261                    }
14262                    pw.println();
14263                } else {
14264                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14265                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14266                    pw.println(voltile);
14267                    pw.print("tuning,");
14268                    pw.print(ActivityManager.staticGetMemoryClass());
14269                    pw.print(',');
14270                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14271                    pw.print(',');
14272                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14273                    if (ActivityManager.isLowRamDeviceStatic()) {
14274                        pw.print(",low-ram");
14275                    }
14276                    if (ActivityManager.isHighEndGfx()) {
14277                        pw.print(",high-end-gfx");
14278                    }
14279                    pw.println();
14280                }
14281            }
14282        }
14283    }
14284
14285    /**
14286     * Searches array of arguments for the specified string
14287     * @param args array of argument strings
14288     * @param value value to search for
14289     * @return true if the value is contained in the array
14290     */
14291    private static boolean scanArgs(String[] args, String value) {
14292        if (args != null) {
14293            for (String arg : args) {
14294                if (value.equals(arg)) {
14295                    return true;
14296                }
14297            }
14298        }
14299        return false;
14300    }
14301
14302    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14303            ContentProviderRecord cpr, boolean always) {
14304        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14305
14306        if (!inLaunching || always) {
14307            synchronized (cpr) {
14308                cpr.launchingApp = null;
14309                cpr.notifyAll();
14310            }
14311            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14312            String names[] = cpr.info.authority.split(";");
14313            for (int j = 0; j < names.length; j++) {
14314                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14315            }
14316        }
14317
14318        for (int i=0; i<cpr.connections.size(); i++) {
14319            ContentProviderConnection conn = cpr.connections.get(i);
14320            if (conn.waiting) {
14321                // If this connection is waiting for the provider, then we don't
14322                // need to mess with its process unless we are always removing
14323                // or for some reason the provider is not currently launching.
14324                if (inLaunching && !always) {
14325                    continue;
14326                }
14327            }
14328            ProcessRecord capp = conn.client;
14329            conn.dead = true;
14330            if (conn.stableCount > 0) {
14331                if (!capp.persistent && capp.thread != null
14332                        && capp.pid != 0
14333                        && capp.pid != MY_PID) {
14334                    capp.kill("depends on provider "
14335                            + cpr.name.flattenToShortString()
14336                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14337                }
14338            } else if (capp.thread != null && conn.provider.provider != null) {
14339                try {
14340                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14341                } catch (RemoteException e) {
14342                }
14343                // In the protocol here, we don't expect the client to correctly
14344                // clean up this connection, we'll just remove it.
14345                cpr.connections.remove(i);
14346                conn.client.conProviders.remove(conn);
14347            }
14348        }
14349
14350        if (inLaunching && always) {
14351            mLaunchingProviders.remove(cpr);
14352        }
14353        return inLaunching;
14354    }
14355
14356    /**
14357     * Main code for cleaning up a process when it has gone away.  This is
14358     * called both as a result of the process dying, or directly when stopping
14359     * a process when running in single process mode.
14360     *
14361     * @return Returns true if the given process has been restarted, so the
14362     * app that was passed in must remain on the process lists.
14363     */
14364    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14365            boolean restarting, boolean allowRestart, int index) {
14366        if (index >= 0) {
14367            removeLruProcessLocked(app);
14368            ProcessList.remove(app.pid);
14369        }
14370
14371        mProcessesToGc.remove(app);
14372        mPendingPssProcesses.remove(app);
14373
14374        // Dismiss any open dialogs.
14375        if (app.crashDialog != null && !app.forceCrashReport) {
14376            app.crashDialog.dismiss();
14377            app.crashDialog = null;
14378        }
14379        if (app.anrDialog != null) {
14380            app.anrDialog.dismiss();
14381            app.anrDialog = null;
14382        }
14383        if (app.waitDialog != null) {
14384            app.waitDialog.dismiss();
14385            app.waitDialog = null;
14386        }
14387
14388        app.crashing = false;
14389        app.notResponding = false;
14390
14391        app.resetPackageList(mProcessStats);
14392        app.unlinkDeathRecipient();
14393        app.makeInactive(mProcessStats);
14394        app.waitingToKill = null;
14395        app.forcingToForeground = null;
14396        updateProcessForegroundLocked(app, false, false);
14397        app.foregroundActivities = false;
14398        app.hasShownUi = false;
14399        app.treatLikeActivity = false;
14400        app.hasAboveClient = false;
14401        app.hasClientActivities = false;
14402
14403        mServices.killServicesLocked(app, allowRestart);
14404
14405        boolean restart = false;
14406
14407        // Remove published content providers.
14408        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14409            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14410            final boolean always = app.bad || !allowRestart;
14411            if (removeDyingProviderLocked(app, cpr, always) || always) {
14412                // We left the provider in the launching list, need to
14413                // restart it.
14414                restart = true;
14415            }
14416
14417            cpr.provider = null;
14418            cpr.proc = null;
14419        }
14420        app.pubProviders.clear();
14421
14422        // Take care of any launching providers waiting for this process.
14423        if (checkAppInLaunchingProvidersLocked(app, false)) {
14424            restart = true;
14425        }
14426
14427        // Unregister from connected content providers.
14428        if (!app.conProviders.isEmpty()) {
14429            for (int i=0; i<app.conProviders.size(); i++) {
14430                ContentProviderConnection conn = app.conProviders.get(i);
14431                conn.provider.connections.remove(conn);
14432            }
14433            app.conProviders.clear();
14434        }
14435
14436        // At this point there may be remaining entries in mLaunchingProviders
14437        // where we were the only one waiting, so they are no longer of use.
14438        // Look for these and clean up if found.
14439        // XXX Commented out for now.  Trying to figure out a way to reproduce
14440        // the actual situation to identify what is actually going on.
14441        if (false) {
14442            for (int i=0; i<mLaunchingProviders.size(); i++) {
14443                ContentProviderRecord cpr = (ContentProviderRecord)
14444                        mLaunchingProviders.get(i);
14445                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14446                    synchronized (cpr) {
14447                        cpr.launchingApp = null;
14448                        cpr.notifyAll();
14449                    }
14450                }
14451            }
14452        }
14453
14454        skipCurrentReceiverLocked(app);
14455
14456        // Unregister any receivers.
14457        for (int i=app.receivers.size()-1; i>=0; i--) {
14458            removeReceiverLocked(app.receivers.valueAt(i));
14459        }
14460        app.receivers.clear();
14461
14462        // If the app is undergoing backup, tell the backup manager about it
14463        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14464            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14465                    + mBackupTarget.appInfo + " died during backup");
14466            try {
14467                IBackupManager bm = IBackupManager.Stub.asInterface(
14468                        ServiceManager.getService(Context.BACKUP_SERVICE));
14469                bm.agentDisconnected(app.info.packageName);
14470            } catch (RemoteException e) {
14471                // can't happen; backup manager is local
14472            }
14473        }
14474
14475        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14476            ProcessChangeItem item = mPendingProcessChanges.get(i);
14477            if (item.pid == app.pid) {
14478                mPendingProcessChanges.remove(i);
14479                mAvailProcessChanges.add(item);
14480            }
14481        }
14482        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14483
14484        // If the caller is restarting this app, then leave it in its
14485        // current lists and let the caller take care of it.
14486        if (restarting) {
14487            return false;
14488        }
14489
14490        if (!app.persistent || app.isolated) {
14491            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14492                    "Removing non-persistent process during cleanup: " + app);
14493            mProcessNames.remove(app.processName, app.uid);
14494            mIsolatedProcesses.remove(app.uid);
14495            if (mHeavyWeightProcess == app) {
14496                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14497                        mHeavyWeightProcess.userId, 0));
14498                mHeavyWeightProcess = null;
14499            }
14500        } else if (!app.removed) {
14501            // This app is persistent, so we need to keep its record around.
14502            // If it is not already on the pending app list, add it there
14503            // and start a new process for it.
14504            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14505                mPersistentStartingProcesses.add(app);
14506                restart = true;
14507            }
14508        }
14509        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14510                "Clean-up removing on hold: " + app);
14511        mProcessesOnHold.remove(app);
14512
14513        if (app == mHomeProcess) {
14514            mHomeProcess = null;
14515        }
14516        if (app == mPreviousProcess) {
14517            mPreviousProcess = null;
14518        }
14519
14520        if (restart && !app.isolated) {
14521            // We have components that still need to be running in the
14522            // process, so re-launch it.
14523            if (index < 0) {
14524                ProcessList.remove(app.pid);
14525            }
14526            mProcessNames.put(app.processName, app.uid, app);
14527            startProcessLocked(app, "restart", app.processName);
14528            return true;
14529        } else if (app.pid > 0 && app.pid != MY_PID) {
14530            // Goodbye!
14531            boolean removed;
14532            synchronized (mPidsSelfLocked) {
14533                mPidsSelfLocked.remove(app.pid);
14534                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14535            }
14536            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14537            if (app.isolated) {
14538                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14539            }
14540            app.setPid(0);
14541        }
14542        return false;
14543    }
14544
14545    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14546        // Look through the content providers we are waiting to have launched,
14547        // and if any run in this process then either schedule a restart of
14548        // the process or kill the client waiting for it if this process has
14549        // gone bad.
14550        int NL = mLaunchingProviders.size();
14551        boolean restart = false;
14552        for (int i=0; i<NL; i++) {
14553            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14554            if (cpr.launchingApp == app) {
14555                if (!alwaysBad && !app.bad) {
14556                    restart = true;
14557                } else {
14558                    removeDyingProviderLocked(app, cpr, true);
14559                    // cpr should have been removed from mLaunchingProviders
14560                    NL = mLaunchingProviders.size();
14561                    i--;
14562                }
14563            }
14564        }
14565        return restart;
14566    }
14567
14568    // =========================================================
14569    // SERVICES
14570    // =========================================================
14571
14572    @Override
14573    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14574            int flags) {
14575        enforceNotIsolatedCaller("getServices");
14576        synchronized (this) {
14577            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14578        }
14579    }
14580
14581    @Override
14582    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14583        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14584        synchronized (this) {
14585            return mServices.getRunningServiceControlPanelLocked(name);
14586        }
14587    }
14588
14589    @Override
14590    public ComponentName startService(IApplicationThread caller, Intent service,
14591            String resolvedType, int userId) {
14592        enforceNotIsolatedCaller("startService");
14593        // Refuse possible leaked file descriptors
14594        if (service != null && service.hasFileDescriptors() == true) {
14595            throw new IllegalArgumentException("File descriptors passed in Intent");
14596        }
14597
14598        if (DEBUG_SERVICE)
14599            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14600        synchronized(this) {
14601            final int callingPid = Binder.getCallingPid();
14602            final int callingUid = Binder.getCallingUid();
14603            final long origId = Binder.clearCallingIdentity();
14604            ComponentName res = mServices.startServiceLocked(caller, service,
14605                    resolvedType, callingPid, callingUid, userId);
14606            Binder.restoreCallingIdentity(origId);
14607            return res;
14608        }
14609    }
14610
14611    ComponentName startServiceInPackage(int uid,
14612            Intent service, String resolvedType, int userId) {
14613        synchronized(this) {
14614            if (DEBUG_SERVICE)
14615                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14616            final long origId = Binder.clearCallingIdentity();
14617            ComponentName res = mServices.startServiceLocked(null, service,
14618                    resolvedType, -1, uid, userId);
14619            Binder.restoreCallingIdentity(origId);
14620            return res;
14621        }
14622    }
14623
14624    @Override
14625    public int stopService(IApplicationThread caller, Intent service,
14626            String resolvedType, int userId) {
14627        enforceNotIsolatedCaller("stopService");
14628        // Refuse possible leaked file descriptors
14629        if (service != null && service.hasFileDescriptors() == true) {
14630            throw new IllegalArgumentException("File descriptors passed in Intent");
14631        }
14632
14633        synchronized(this) {
14634            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14635        }
14636    }
14637
14638    @Override
14639    public IBinder peekService(Intent service, String resolvedType) {
14640        enforceNotIsolatedCaller("peekService");
14641        // Refuse possible leaked file descriptors
14642        if (service != null && service.hasFileDescriptors() == true) {
14643            throw new IllegalArgumentException("File descriptors passed in Intent");
14644        }
14645        synchronized(this) {
14646            return mServices.peekServiceLocked(service, resolvedType);
14647        }
14648    }
14649
14650    @Override
14651    public boolean stopServiceToken(ComponentName className, IBinder token,
14652            int startId) {
14653        synchronized(this) {
14654            return mServices.stopServiceTokenLocked(className, token, startId);
14655        }
14656    }
14657
14658    @Override
14659    public void setServiceForeground(ComponentName className, IBinder token,
14660            int id, Notification notification, boolean removeNotification) {
14661        synchronized(this) {
14662            mServices.setServiceForegroundLocked(className, token, id, notification,
14663                    removeNotification);
14664        }
14665    }
14666
14667    @Override
14668    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14669            boolean requireFull, String name, String callerPackage) {
14670        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14671                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14672    }
14673
14674    int unsafeConvertIncomingUser(int userId) {
14675        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14676                ? mCurrentUserId : userId;
14677    }
14678
14679    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14680            int allowMode, String name, String callerPackage) {
14681        final int callingUserId = UserHandle.getUserId(callingUid);
14682        if (callingUserId == userId) {
14683            return userId;
14684        }
14685
14686        // Note that we may be accessing mCurrentUserId outside of a lock...
14687        // shouldn't be a big deal, if this is being called outside
14688        // of a locked context there is intrinsically a race with
14689        // the value the caller will receive and someone else changing it.
14690        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14691        // we will switch to the calling user if access to the current user fails.
14692        int targetUserId = unsafeConvertIncomingUser(userId);
14693
14694        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14695            final boolean allow;
14696            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14697                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14698                // If the caller has this permission, they always pass go.  And collect $200.
14699                allow = true;
14700            } else if (allowMode == ALLOW_FULL_ONLY) {
14701                // We require full access, sucks to be you.
14702                allow = false;
14703            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14704                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14705                // If the caller does not have either permission, they are always doomed.
14706                allow = false;
14707            } else if (allowMode == ALLOW_NON_FULL) {
14708                // We are blanket allowing non-full access, you lucky caller!
14709                allow = true;
14710            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14711                // We may or may not allow this depending on whether the two users are
14712                // in the same profile.
14713                synchronized (mUserProfileGroupIdsSelfLocked) {
14714                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14715                            UserInfo.NO_PROFILE_GROUP_ID);
14716                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14717                            UserInfo.NO_PROFILE_GROUP_ID);
14718                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14719                            && callingProfile == targetProfile;
14720                }
14721            } else {
14722                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14723            }
14724            if (!allow) {
14725                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14726                    // In this case, they would like to just execute as their
14727                    // owner user instead of failing.
14728                    targetUserId = callingUserId;
14729                } else {
14730                    StringBuilder builder = new StringBuilder(128);
14731                    builder.append("Permission Denial: ");
14732                    builder.append(name);
14733                    if (callerPackage != null) {
14734                        builder.append(" from ");
14735                        builder.append(callerPackage);
14736                    }
14737                    builder.append(" asks to run as user ");
14738                    builder.append(userId);
14739                    builder.append(" but is calling from user ");
14740                    builder.append(UserHandle.getUserId(callingUid));
14741                    builder.append("; this requires ");
14742                    builder.append(INTERACT_ACROSS_USERS_FULL);
14743                    if (allowMode != ALLOW_FULL_ONLY) {
14744                        builder.append(" or ");
14745                        builder.append(INTERACT_ACROSS_USERS);
14746                    }
14747                    String msg = builder.toString();
14748                    Slog.w(TAG, msg);
14749                    throw new SecurityException(msg);
14750                }
14751            }
14752        }
14753        if (!allowAll && targetUserId < 0) {
14754            throw new IllegalArgumentException(
14755                    "Call does not support special user #" + targetUserId);
14756        }
14757        // Check shell permission
14758        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14759            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14760                    targetUserId)) {
14761                throw new SecurityException("Shell does not have permission to access user "
14762                        + targetUserId + "\n " + Debug.getCallers(3));
14763            }
14764        }
14765        return targetUserId;
14766    }
14767
14768    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14769            String className, int flags) {
14770        boolean result = false;
14771        // For apps that don't have pre-defined UIDs, check for permission
14772        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14773            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14774                if (ActivityManager.checkUidPermission(
14775                        INTERACT_ACROSS_USERS,
14776                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14777                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14778                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14779                            + " requests FLAG_SINGLE_USER, but app does not hold "
14780                            + INTERACT_ACROSS_USERS;
14781                    Slog.w(TAG, msg);
14782                    throw new SecurityException(msg);
14783                }
14784                // Permission passed
14785                result = true;
14786            }
14787        } else if ("system".equals(componentProcessName)) {
14788            result = true;
14789        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14790            // Phone app and persistent apps are allowed to export singleuser providers.
14791            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14792                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14793        }
14794        if (DEBUG_MU) {
14795            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14796                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14797        }
14798        return result;
14799    }
14800
14801    /**
14802     * Checks to see if the caller is in the same app as the singleton
14803     * component, or the component is in a special app. It allows special apps
14804     * to export singleton components but prevents exporting singleton
14805     * components for regular apps.
14806     */
14807    boolean isValidSingletonCall(int callingUid, int componentUid) {
14808        int componentAppId = UserHandle.getAppId(componentUid);
14809        return UserHandle.isSameApp(callingUid, componentUid)
14810                || componentAppId == Process.SYSTEM_UID
14811                || componentAppId == Process.PHONE_UID
14812                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14813                        == PackageManager.PERMISSION_GRANTED;
14814    }
14815
14816    public int bindService(IApplicationThread caller, IBinder token,
14817            Intent service, String resolvedType,
14818            IServiceConnection connection, int flags, int userId) {
14819        enforceNotIsolatedCaller("bindService");
14820
14821        // Refuse possible leaked file descriptors
14822        if (service != null && service.hasFileDescriptors() == true) {
14823            throw new IllegalArgumentException("File descriptors passed in Intent");
14824        }
14825
14826        synchronized(this) {
14827            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14828                    connection, flags, userId);
14829        }
14830    }
14831
14832    public boolean unbindService(IServiceConnection connection) {
14833        synchronized (this) {
14834            return mServices.unbindServiceLocked(connection);
14835        }
14836    }
14837
14838    public void publishService(IBinder token, Intent intent, IBinder service) {
14839        // Refuse possible leaked file descriptors
14840        if (intent != null && intent.hasFileDescriptors() == true) {
14841            throw new IllegalArgumentException("File descriptors passed in Intent");
14842        }
14843
14844        synchronized(this) {
14845            if (!(token instanceof ServiceRecord)) {
14846                throw new IllegalArgumentException("Invalid service token");
14847            }
14848            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14849        }
14850    }
14851
14852    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14853        // Refuse possible leaked file descriptors
14854        if (intent != null && intent.hasFileDescriptors() == true) {
14855            throw new IllegalArgumentException("File descriptors passed in Intent");
14856        }
14857
14858        synchronized(this) {
14859            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14860        }
14861    }
14862
14863    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14864        synchronized(this) {
14865            if (!(token instanceof ServiceRecord)) {
14866                throw new IllegalArgumentException("Invalid service token");
14867            }
14868            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14869        }
14870    }
14871
14872    // =========================================================
14873    // BACKUP AND RESTORE
14874    // =========================================================
14875
14876    // Cause the target app to be launched if necessary and its backup agent
14877    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14878    // activity manager to announce its creation.
14879    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14880        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14881        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14882
14883        synchronized(this) {
14884            // !!! TODO: currently no check here that we're already bound
14885            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14886            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14887            synchronized (stats) {
14888                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14889            }
14890
14891            // Backup agent is now in use, its package can't be stopped.
14892            try {
14893                AppGlobals.getPackageManager().setPackageStoppedState(
14894                        app.packageName, false, UserHandle.getUserId(app.uid));
14895            } catch (RemoteException e) {
14896            } catch (IllegalArgumentException e) {
14897                Slog.w(TAG, "Failed trying to unstop package "
14898                        + app.packageName + ": " + e);
14899            }
14900
14901            BackupRecord r = new BackupRecord(ss, app, backupMode);
14902            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14903                    ? new ComponentName(app.packageName, app.backupAgentName)
14904                    : new ComponentName("android", "FullBackupAgent");
14905            // startProcessLocked() returns existing proc's record if it's already running
14906            ProcessRecord proc = startProcessLocked(app.processName, app,
14907                    false, 0, "backup", hostingName, false, false, false);
14908            if (proc == null) {
14909                Slog.e(TAG, "Unable to start backup agent process " + r);
14910                return false;
14911            }
14912
14913            r.app = proc;
14914            mBackupTarget = r;
14915            mBackupAppName = app.packageName;
14916
14917            // Try not to kill the process during backup
14918            updateOomAdjLocked(proc);
14919
14920            // If the process is already attached, schedule the creation of the backup agent now.
14921            // If it is not yet live, this will be done when it attaches to the framework.
14922            if (proc.thread != null) {
14923                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14924                try {
14925                    proc.thread.scheduleCreateBackupAgent(app,
14926                            compatibilityInfoForPackageLocked(app), backupMode);
14927                } catch (RemoteException e) {
14928                    // Will time out on the backup manager side
14929                }
14930            } else {
14931                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14932            }
14933            // Invariants: at this point, the target app process exists and the application
14934            // is either already running or in the process of coming up.  mBackupTarget and
14935            // mBackupAppName describe the app, so that when it binds back to the AM we
14936            // know that it's scheduled for a backup-agent operation.
14937        }
14938
14939        return true;
14940    }
14941
14942    @Override
14943    public void clearPendingBackup() {
14944        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14945        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14946
14947        synchronized (this) {
14948            mBackupTarget = null;
14949            mBackupAppName = null;
14950        }
14951    }
14952
14953    // A backup agent has just come up
14954    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14955        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14956                + " = " + agent);
14957
14958        synchronized(this) {
14959            if (!agentPackageName.equals(mBackupAppName)) {
14960                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14961                return;
14962            }
14963        }
14964
14965        long oldIdent = Binder.clearCallingIdentity();
14966        try {
14967            IBackupManager bm = IBackupManager.Stub.asInterface(
14968                    ServiceManager.getService(Context.BACKUP_SERVICE));
14969            bm.agentConnected(agentPackageName, agent);
14970        } catch (RemoteException e) {
14971            // can't happen; the backup manager service is local
14972        } catch (Exception e) {
14973            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14974            e.printStackTrace();
14975        } finally {
14976            Binder.restoreCallingIdentity(oldIdent);
14977        }
14978    }
14979
14980    // done with this agent
14981    public void unbindBackupAgent(ApplicationInfo appInfo) {
14982        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14983        if (appInfo == null) {
14984            Slog.w(TAG, "unbind backup agent for null app");
14985            return;
14986        }
14987
14988        synchronized(this) {
14989            try {
14990                if (mBackupAppName == null) {
14991                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14992                    return;
14993                }
14994
14995                if (!mBackupAppName.equals(appInfo.packageName)) {
14996                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14997                    return;
14998                }
14999
15000                // Not backing this app up any more; reset its OOM adjustment
15001                final ProcessRecord proc = mBackupTarget.app;
15002                updateOomAdjLocked(proc);
15003
15004                // If the app crashed during backup, 'thread' will be null here
15005                if (proc.thread != null) {
15006                    try {
15007                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15008                                compatibilityInfoForPackageLocked(appInfo));
15009                    } catch (Exception e) {
15010                        Slog.e(TAG, "Exception when unbinding backup agent:");
15011                        e.printStackTrace();
15012                    }
15013                }
15014            } finally {
15015                mBackupTarget = null;
15016                mBackupAppName = null;
15017            }
15018        }
15019    }
15020    // =========================================================
15021    // BROADCASTS
15022    // =========================================================
15023
15024    private final List getStickiesLocked(String action, IntentFilter filter,
15025            List cur, int userId) {
15026        final ContentResolver resolver = mContext.getContentResolver();
15027        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15028        if (stickies == null) {
15029            return cur;
15030        }
15031        final ArrayList<Intent> list = stickies.get(action);
15032        if (list == null) {
15033            return cur;
15034        }
15035        int N = list.size();
15036        for (int i=0; i<N; i++) {
15037            Intent intent = list.get(i);
15038            if (filter.match(resolver, intent, true, TAG) >= 0) {
15039                if (cur == null) {
15040                    cur = new ArrayList<Intent>();
15041                }
15042                cur.add(intent);
15043            }
15044        }
15045        return cur;
15046    }
15047
15048    boolean isPendingBroadcastProcessLocked(int pid) {
15049        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15050                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15051    }
15052
15053    void skipPendingBroadcastLocked(int pid) {
15054            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15055            for (BroadcastQueue queue : mBroadcastQueues) {
15056                queue.skipPendingBroadcastLocked(pid);
15057            }
15058    }
15059
15060    // The app just attached; send any pending broadcasts that it should receive
15061    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15062        boolean didSomething = false;
15063        for (BroadcastQueue queue : mBroadcastQueues) {
15064            didSomething |= queue.sendPendingBroadcastsLocked(app);
15065        }
15066        return didSomething;
15067    }
15068
15069    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15070            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15071        enforceNotIsolatedCaller("registerReceiver");
15072        int callingUid;
15073        int callingPid;
15074        synchronized(this) {
15075            ProcessRecord callerApp = null;
15076            if (caller != null) {
15077                callerApp = getRecordForAppLocked(caller);
15078                if (callerApp == null) {
15079                    throw new SecurityException(
15080                            "Unable to find app for caller " + caller
15081                            + " (pid=" + Binder.getCallingPid()
15082                            + ") when registering receiver " + receiver);
15083                }
15084                if (callerApp.info.uid != Process.SYSTEM_UID &&
15085                        !callerApp.pkgList.containsKey(callerPackage) &&
15086                        !"android".equals(callerPackage)) {
15087                    throw new SecurityException("Given caller package " + callerPackage
15088                            + " is not running in process " + callerApp);
15089                }
15090                callingUid = callerApp.info.uid;
15091                callingPid = callerApp.pid;
15092            } else {
15093                callerPackage = null;
15094                callingUid = Binder.getCallingUid();
15095                callingPid = Binder.getCallingPid();
15096            }
15097
15098            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15099                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15100
15101            List allSticky = null;
15102
15103            // Look for any matching sticky broadcasts...
15104            Iterator actions = filter.actionsIterator();
15105            if (actions != null) {
15106                while (actions.hasNext()) {
15107                    String action = (String)actions.next();
15108                    allSticky = getStickiesLocked(action, filter, allSticky,
15109                            UserHandle.USER_ALL);
15110                    allSticky = getStickiesLocked(action, filter, allSticky,
15111                            UserHandle.getUserId(callingUid));
15112                }
15113            } else {
15114                allSticky = getStickiesLocked(null, filter, allSticky,
15115                        UserHandle.USER_ALL);
15116                allSticky = getStickiesLocked(null, filter, allSticky,
15117                        UserHandle.getUserId(callingUid));
15118            }
15119
15120            // The first sticky in the list is returned directly back to
15121            // the client.
15122            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15123
15124            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15125                    + ": " + sticky);
15126
15127            if (receiver == null) {
15128                return sticky;
15129            }
15130
15131            ReceiverList rl
15132                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15133            if (rl == null) {
15134                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15135                        userId, receiver);
15136                if (rl.app != null) {
15137                    rl.app.receivers.add(rl);
15138                } else {
15139                    try {
15140                        receiver.asBinder().linkToDeath(rl, 0);
15141                    } catch (RemoteException e) {
15142                        return sticky;
15143                    }
15144                    rl.linkedToDeath = true;
15145                }
15146                mRegisteredReceivers.put(receiver.asBinder(), rl);
15147            } else if (rl.uid != callingUid) {
15148                throw new IllegalArgumentException(
15149                        "Receiver requested to register for uid " + callingUid
15150                        + " was previously registered for uid " + rl.uid);
15151            } else if (rl.pid != callingPid) {
15152                throw new IllegalArgumentException(
15153                        "Receiver requested to register for pid " + callingPid
15154                        + " was previously registered for pid " + rl.pid);
15155            } else if (rl.userId != userId) {
15156                throw new IllegalArgumentException(
15157                        "Receiver requested to register for user " + userId
15158                        + " was previously registered for user " + rl.userId);
15159            }
15160            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15161                    permission, callingUid, userId);
15162            rl.add(bf);
15163            if (!bf.debugCheck()) {
15164                Slog.w(TAG, "==> For Dynamic broadast");
15165            }
15166            mReceiverResolver.addFilter(bf);
15167
15168            // Enqueue broadcasts for all existing stickies that match
15169            // this filter.
15170            if (allSticky != null) {
15171                ArrayList receivers = new ArrayList();
15172                receivers.add(bf);
15173
15174                int N = allSticky.size();
15175                for (int i=0; i<N; i++) {
15176                    Intent intent = (Intent)allSticky.get(i);
15177                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15178                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15179                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15180                            null, null, false, true, true, -1);
15181                    queue.enqueueParallelBroadcastLocked(r);
15182                    queue.scheduleBroadcastsLocked();
15183                }
15184            }
15185
15186            return sticky;
15187        }
15188    }
15189
15190    public void unregisterReceiver(IIntentReceiver receiver) {
15191        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15192
15193        final long origId = Binder.clearCallingIdentity();
15194        try {
15195            boolean doTrim = false;
15196
15197            synchronized(this) {
15198                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15199                if (rl != null) {
15200                    if (rl.curBroadcast != null) {
15201                        BroadcastRecord r = rl.curBroadcast;
15202                        final boolean doNext = finishReceiverLocked(
15203                                receiver.asBinder(), r.resultCode, r.resultData,
15204                                r.resultExtras, r.resultAbort);
15205                        if (doNext) {
15206                            doTrim = true;
15207                            r.queue.processNextBroadcast(false);
15208                        }
15209                    }
15210
15211                    if (rl.app != null) {
15212                        rl.app.receivers.remove(rl);
15213                    }
15214                    removeReceiverLocked(rl);
15215                    if (rl.linkedToDeath) {
15216                        rl.linkedToDeath = false;
15217                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15218                    }
15219                }
15220            }
15221
15222            // If we actually concluded any broadcasts, we might now be able
15223            // to trim the recipients' apps from our working set
15224            if (doTrim) {
15225                trimApplications();
15226                return;
15227            }
15228
15229        } finally {
15230            Binder.restoreCallingIdentity(origId);
15231        }
15232    }
15233
15234    void removeReceiverLocked(ReceiverList rl) {
15235        mRegisteredReceivers.remove(rl.receiver.asBinder());
15236        int N = rl.size();
15237        for (int i=0; i<N; i++) {
15238            mReceiverResolver.removeFilter(rl.get(i));
15239        }
15240    }
15241
15242    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15243        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15244            ProcessRecord r = mLruProcesses.get(i);
15245            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15246                try {
15247                    r.thread.dispatchPackageBroadcast(cmd, packages);
15248                } catch (RemoteException ex) {
15249                }
15250            }
15251        }
15252    }
15253
15254    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15255            int callingUid, int[] users) {
15256        List<ResolveInfo> receivers = null;
15257        try {
15258            HashSet<ComponentName> singleUserReceivers = null;
15259            boolean scannedFirstReceivers = false;
15260            for (int user : users) {
15261                // Skip users that have Shell restrictions
15262                if (callingUid == Process.SHELL_UID
15263                        && getUserManagerLocked().hasUserRestriction(
15264                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15265                    continue;
15266                }
15267                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15268                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15269                if (user != 0 && newReceivers != null) {
15270                    // If this is not the primary user, we need to check for
15271                    // any receivers that should be filtered out.
15272                    for (int i=0; i<newReceivers.size(); i++) {
15273                        ResolveInfo ri = newReceivers.get(i);
15274                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15275                            newReceivers.remove(i);
15276                            i--;
15277                        }
15278                    }
15279                }
15280                if (newReceivers != null && newReceivers.size() == 0) {
15281                    newReceivers = null;
15282                }
15283                if (receivers == null) {
15284                    receivers = newReceivers;
15285                } else if (newReceivers != null) {
15286                    // We need to concatenate the additional receivers
15287                    // found with what we have do far.  This would be easy,
15288                    // but we also need to de-dup any receivers that are
15289                    // singleUser.
15290                    if (!scannedFirstReceivers) {
15291                        // Collect any single user receivers we had already retrieved.
15292                        scannedFirstReceivers = true;
15293                        for (int i=0; i<receivers.size(); i++) {
15294                            ResolveInfo ri = receivers.get(i);
15295                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15296                                ComponentName cn = new ComponentName(
15297                                        ri.activityInfo.packageName, ri.activityInfo.name);
15298                                if (singleUserReceivers == null) {
15299                                    singleUserReceivers = new HashSet<ComponentName>();
15300                                }
15301                                singleUserReceivers.add(cn);
15302                            }
15303                        }
15304                    }
15305                    // Add the new results to the existing results, tracking
15306                    // and de-dupping single user receivers.
15307                    for (int i=0; i<newReceivers.size(); i++) {
15308                        ResolveInfo ri = newReceivers.get(i);
15309                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15310                            ComponentName cn = new ComponentName(
15311                                    ri.activityInfo.packageName, ri.activityInfo.name);
15312                            if (singleUserReceivers == null) {
15313                                singleUserReceivers = new HashSet<ComponentName>();
15314                            }
15315                            if (!singleUserReceivers.contains(cn)) {
15316                                singleUserReceivers.add(cn);
15317                                receivers.add(ri);
15318                            }
15319                        } else {
15320                            receivers.add(ri);
15321                        }
15322                    }
15323                }
15324            }
15325        } catch (RemoteException ex) {
15326            // pm is in same process, this will never happen.
15327        }
15328        return receivers;
15329    }
15330
15331    private final int broadcastIntentLocked(ProcessRecord callerApp,
15332            String callerPackage, Intent intent, String resolvedType,
15333            IIntentReceiver resultTo, int resultCode, String resultData,
15334            Bundle map, String requiredPermission, int appOp,
15335            boolean ordered, boolean sticky, int callingPid, int callingUid,
15336            int userId) {
15337        intent = new Intent(intent);
15338
15339        // By default broadcasts do not go to stopped apps.
15340        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15341
15342        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15343            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15344            + " ordered=" + ordered + " userid=" + userId);
15345        if ((resultTo != null) && !ordered) {
15346            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15347        }
15348
15349        userId = handleIncomingUser(callingPid, callingUid, userId,
15350                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15351
15352        // Make sure that the user who is receiving this broadcast is started.
15353        // If not, we will just skip it.
15354
15355        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15356            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15357                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15358                Slog.w(TAG, "Skipping broadcast of " + intent
15359                        + ": user " + userId + " is stopped");
15360                return ActivityManager.BROADCAST_SUCCESS;
15361            }
15362        }
15363
15364        /*
15365         * Prevent non-system code (defined here to be non-persistent
15366         * processes) from sending protected broadcasts.
15367         */
15368        int callingAppId = UserHandle.getAppId(callingUid);
15369        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15370            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15371            || callingAppId == Process.NFC_UID || callingUid == 0) {
15372            // Always okay.
15373        } else if (callerApp == null || !callerApp.persistent) {
15374            try {
15375                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15376                        intent.getAction())) {
15377                    String msg = "Permission Denial: not allowed to send broadcast "
15378                            + intent.getAction() + " from pid="
15379                            + callingPid + ", uid=" + callingUid;
15380                    Slog.w(TAG, msg);
15381                    throw new SecurityException(msg);
15382                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15383                    // Special case for compatibility: we don't want apps to send this,
15384                    // but historically it has not been protected and apps may be using it
15385                    // to poke their own app widget.  So, instead of making it protected,
15386                    // just limit it to the caller.
15387                    if (callerApp == null) {
15388                        String msg = "Permission Denial: not allowed to send broadcast "
15389                                + intent.getAction() + " from unknown caller.";
15390                        Slog.w(TAG, msg);
15391                        throw new SecurityException(msg);
15392                    } else if (intent.getComponent() != null) {
15393                        // They are good enough to send to an explicit component...  verify
15394                        // it is being sent to the calling app.
15395                        if (!intent.getComponent().getPackageName().equals(
15396                                callerApp.info.packageName)) {
15397                            String msg = "Permission Denial: not allowed to send broadcast "
15398                                    + intent.getAction() + " to "
15399                                    + intent.getComponent().getPackageName() + " from "
15400                                    + callerApp.info.packageName;
15401                            Slog.w(TAG, msg);
15402                            throw new SecurityException(msg);
15403                        }
15404                    } else {
15405                        // Limit broadcast to their own package.
15406                        intent.setPackage(callerApp.info.packageName);
15407                    }
15408                }
15409            } catch (RemoteException e) {
15410                Slog.w(TAG, "Remote exception", e);
15411                return ActivityManager.BROADCAST_SUCCESS;
15412            }
15413        }
15414
15415        // Handle special intents: if this broadcast is from the package
15416        // manager about a package being removed, we need to remove all of
15417        // its activities from the history stack.
15418        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15419                intent.getAction());
15420        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15421                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15422                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15423                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15424                || uidRemoved) {
15425            if (checkComponentPermission(
15426                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15427                    callingPid, callingUid, -1, true)
15428                    == PackageManager.PERMISSION_GRANTED) {
15429                if (uidRemoved) {
15430                    final Bundle intentExtras = intent.getExtras();
15431                    final int uid = intentExtras != null
15432                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15433                    if (uid >= 0) {
15434                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15435                        synchronized (bs) {
15436                            bs.removeUidStatsLocked(uid);
15437                        }
15438                        mAppOpsService.uidRemoved(uid);
15439                    }
15440                } else {
15441                    // If resources are unavailable just force stop all
15442                    // those packages and flush the attribute cache as well.
15443                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15444                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15445                        if (list != null && (list.length > 0)) {
15446                            for (String pkg : list) {
15447                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15448                                        "storage unmount");
15449                            }
15450                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15451                            sendPackageBroadcastLocked(
15452                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15453                        }
15454                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15455                            intent.getAction())) {
15456                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15457                    } else {
15458                        Uri data = intent.getData();
15459                        String ssp;
15460                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15461                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15462                                    intent.getAction());
15463                            boolean fullUninstall = removed &&
15464                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15465                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15466                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15467                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15468                                        false, fullUninstall, userId,
15469                                        removed ? "pkg removed" : "pkg changed");
15470                            }
15471                            if (removed) {
15472                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15473                                        new String[] {ssp}, userId);
15474                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15475                                    mAppOpsService.packageRemoved(
15476                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15477
15478                                    // Remove all permissions granted from/to this package
15479                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15480                                }
15481                            }
15482                        }
15483                    }
15484                }
15485            } else {
15486                String msg = "Permission Denial: " + intent.getAction()
15487                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15488                        + ", uid=" + callingUid + ")"
15489                        + " requires "
15490                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15491                Slog.w(TAG, msg);
15492                throw new SecurityException(msg);
15493            }
15494
15495        // Special case for adding a package: by default turn on compatibility
15496        // mode.
15497        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15498            Uri data = intent.getData();
15499            String ssp;
15500            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15501                mCompatModePackages.handlePackageAddedLocked(ssp,
15502                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15503            }
15504        }
15505
15506        /*
15507         * If this is the time zone changed action, queue up a message that will reset the timezone
15508         * of all currently running processes. This message will get queued up before the broadcast
15509         * happens.
15510         */
15511        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15512            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15513        }
15514
15515        /*
15516         * If the user set the time, let all running processes know.
15517         */
15518        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15519            final int is24Hour = intent.getBooleanExtra(
15520                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15521            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15522            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15523            synchronized (stats) {
15524                stats.noteCurrentTimeChangedLocked();
15525            }
15526        }
15527
15528        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15529            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15530        }
15531
15532        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15533            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15534            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15535        }
15536
15537        // Add to the sticky list if requested.
15538        if (sticky) {
15539            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15540                    callingPid, callingUid)
15541                    != PackageManager.PERMISSION_GRANTED) {
15542                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15543                        + callingPid + ", uid=" + callingUid
15544                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15545                Slog.w(TAG, msg);
15546                throw new SecurityException(msg);
15547            }
15548            if (requiredPermission != null) {
15549                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15550                        + " and enforce permission " + requiredPermission);
15551                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15552            }
15553            if (intent.getComponent() != null) {
15554                throw new SecurityException(
15555                        "Sticky broadcasts can't target a specific component");
15556            }
15557            // We use userId directly here, since the "all" target is maintained
15558            // as a separate set of sticky broadcasts.
15559            if (userId != UserHandle.USER_ALL) {
15560                // But first, if this is not a broadcast to all users, then
15561                // make sure it doesn't conflict with an existing broadcast to
15562                // all users.
15563                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15564                        UserHandle.USER_ALL);
15565                if (stickies != null) {
15566                    ArrayList<Intent> list = stickies.get(intent.getAction());
15567                    if (list != null) {
15568                        int N = list.size();
15569                        int i;
15570                        for (i=0; i<N; i++) {
15571                            if (intent.filterEquals(list.get(i))) {
15572                                throw new IllegalArgumentException(
15573                                        "Sticky broadcast " + intent + " for user "
15574                                        + userId + " conflicts with existing global broadcast");
15575                            }
15576                        }
15577                    }
15578                }
15579            }
15580            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15581            if (stickies == null) {
15582                stickies = new ArrayMap<String, ArrayList<Intent>>();
15583                mStickyBroadcasts.put(userId, stickies);
15584            }
15585            ArrayList<Intent> list = stickies.get(intent.getAction());
15586            if (list == null) {
15587                list = new ArrayList<Intent>();
15588                stickies.put(intent.getAction(), list);
15589            }
15590            int N = list.size();
15591            int i;
15592            for (i=0; i<N; i++) {
15593                if (intent.filterEquals(list.get(i))) {
15594                    // This sticky already exists, replace it.
15595                    list.set(i, new Intent(intent));
15596                    break;
15597                }
15598            }
15599            if (i >= N) {
15600                list.add(new Intent(intent));
15601            }
15602        }
15603
15604        int[] users;
15605        if (userId == UserHandle.USER_ALL) {
15606            // Caller wants broadcast to go to all started users.
15607            users = mStartedUserArray;
15608        } else {
15609            // Caller wants broadcast to go to one specific user.
15610            users = new int[] {userId};
15611        }
15612
15613        // Figure out who all will receive this broadcast.
15614        List receivers = null;
15615        List<BroadcastFilter> registeredReceivers = null;
15616        // Need to resolve the intent to interested receivers...
15617        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15618                 == 0) {
15619            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15620        }
15621        if (intent.getComponent() == null) {
15622            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15623                // Query one target user at a time, excluding shell-restricted users
15624                UserManagerService ums = getUserManagerLocked();
15625                for (int i = 0; i < users.length; i++) {
15626                    if (ums.hasUserRestriction(
15627                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15628                        continue;
15629                    }
15630                    List<BroadcastFilter> registeredReceiversForUser =
15631                            mReceiverResolver.queryIntent(intent,
15632                                    resolvedType, false, users[i]);
15633                    if (registeredReceivers == null) {
15634                        registeredReceivers = registeredReceiversForUser;
15635                    } else if (registeredReceiversForUser != null) {
15636                        registeredReceivers.addAll(registeredReceiversForUser);
15637                    }
15638                }
15639            } else {
15640                registeredReceivers = mReceiverResolver.queryIntent(intent,
15641                        resolvedType, false, userId);
15642            }
15643        }
15644
15645        final boolean replacePending =
15646                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15647
15648        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15649                + " replacePending=" + replacePending);
15650
15651        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15652        if (!ordered && NR > 0) {
15653            // If we are not serializing this broadcast, then send the
15654            // registered receivers separately so they don't wait for the
15655            // components to be launched.
15656            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15657            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15658                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15659                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15660                    ordered, sticky, false, userId);
15661            if (DEBUG_BROADCAST) Slog.v(
15662                    TAG, "Enqueueing parallel broadcast " + r);
15663            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15664            if (!replaced) {
15665                queue.enqueueParallelBroadcastLocked(r);
15666                queue.scheduleBroadcastsLocked();
15667            }
15668            registeredReceivers = null;
15669            NR = 0;
15670        }
15671
15672        // Merge into one list.
15673        int ir = 0;
15674        if (receivers != null) {
15675            // A special case for PACKAGE_ADDED: do not allow the package
15676            // being added to see this broadcast.  This prevents them from
15677            // using this as a back door to get run as soon as they are
15678            // installed.  Maybe in the future we want to have a special install
15679            // broadcast or such for apps, but we'd like to deliberately make
15680            // this decision.
15681            String skipPackages[] = null;
15682            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15683                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15684                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15685                Uri data = intent.getData();
15686                if (data != null) {
15687                    String pkgName = data.getSchemeSpecificPart();
15688                    if (pkgName != null) {
15689                        skipPackages = new String[] { pkgName };
15690                    }
15691                }
15692            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15693                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15694            }
15695            if (skipPackages != null && (skipPackages.length > 0)) {
15696                for (String skipPackage : skipPackages) {
15697                    if (skipPackage != null) {
15698                        int NT = receivers.size();
15699                        for (int it=0; it<NT; it++) {
15700                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15701                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15702                                receivers.remove(it);
15703                                it--;
15704                                NT--;
15705                            }
15706                        }
15707                    }
15708                }
15709            }
15710
15711            int NT = receivers != null ? receivers.size() : 0;
15712            int it = 0;
15713            ResolveInfo curt = null;
15714            BroadcastFilter curr = null;
15715            while (it < NT && ir < NR) {
15716                if (curt == null) {
15717                    curt = (ResolveInfo)receivers.get(it);
15718                }
15719                if (curr == null) {
15720                    curr = registeredReceivers.get(ir);
15721                }
15722                if (curr.getPriority() >= curt.priority) {
15723                    // Insert this broadcast record into the final list.
15724                    receivers.add(it, curr);
15725                    ir++;
15726                    curr = null;
15727                    it++;
15728                    NT++;
15729                } else {
15730                    // Skip to the next ResolveInfo in the final list.
15731                    it++;
15732                    curt = null;
15733                }
15734            }
15735        }
15736        while (ir < NR) {
15737            if (receivers == null) {
15738                receivers = new ArrayList();
15739            }
15740            receivers.add(registeredReceivers.get(ir));
15741            ir++;
15742        }
15743
15744        if ((receivers != null && receivers.size() > 0)
15745                || resultTo != null) {
15746            BroadcastQueue queue = broadcastQueueForIntent(intent);
15747            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15748                    callerPackage, callingPid, callingUid, resolvedType,
15749                    requiredPermission, appOp, receivers, resultTo, resultCode,
15750                    resultData, map, ordered, sticky, false, userId);
15751            if (DEBUG_BROADCAST) Slog.v(
15752                    TAG, "Enqueueing ordered broadcast " + r
15753                    + ": prev had " + queue.mOrderedBroadcasts.size());
15754            if (DEBUG_BROADCAST) {
15755                int seq = r.intent.getIntExtra("seq", -1);
15756                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15757            }
15758            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15759            if (!replaced) {
15760                queue.enqueueOrderedBroadcastLocked(r);
15761                queue.scheduleBroadcastsLocked();
15762            }
15763        }
15764
15765        return ActivityManager.BROADCAST_SUCCESS;
15766    }
15767
15768    final Intent verifyBroadcastLocked(Intent intent) {
15769        // Refuse possible leaked file descriptors
15770        if (intent != null && intent.hasFileDescriptors() == true) {
15771            throw new IllegalArgumentException("File descriptors passed in Intent");
15772        }
15773
15774        int flags = intent.getFlags();
15775
15776        if (!mProcessesReady) {
15777            // if the caller really truly claims to know what they're doing, go
15778            // ahead and allow the broadcast without launching any receivers
15779            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15780                intent = new Intent(intent);
15781                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15782            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15783                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15784                        + " before boot completion");
15785                throw new IllegalStateException("Cannot broadcast before boot completed");
15786            }
15787        }
15788
15789        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15790            throw new IllegalArgumentException(
15791                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15792        }
15793
15794        return intent;
15795    }
15796
15797    public final int broadcastIntent(IApplicationThread caller,
15798            Intent intent, String resolvedType, IIntentReceiver resultTo,
15799            int resultCode, String resultData, Bundle map,
15800            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15801        enforceNotIsolatedCaller("broadcastIntent");
15802        synchronized(this) {
15803            intent = verifyBroadcastLocked(intent);
15804
15805            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15806            final int callingPid = Binder.getCallingPid();
15807            final int callingUid = Binder.getCallingUid();
15808            final long origId = Binder.clearCallingIdentity();
15809            int res = broadcastIntentLocked(callerApp,
15810                    callerApp != null ? callerApp.info.packageName : null,
15811                    intent, resolvedType, resultTo,
15812                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15813                    callingPid, callingUid, userId);
15814            Binder.restoreCallingIdentity(origId);
15815            return res;
15816        }
15817    }
15818
15819    int broadcastIntentInPackage(String packageName, int uid,
15820            Intent intent, String resolvedType, IIntentReceiver resultTo,
15821            int resultCode, String resultData, Bundle map,
15822            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15823        synchronized(this) {
15824            intent = verifyBroadcastLocked(intent);
15825
15826            final long origId = Binder.clearCallingIdentity();
15827            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15828                    resultTo, resultCode, resultData, map, requiredPermission,
15829                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15830            Binder.restoreCallingIdentity(origId);
15831            return res;
15832        }
15833    }
15834
15835    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15836        // Refuse possible leaked file descriptors
15837        if (intent != null && intent.hasFileDescriptors() == true) {
15838            throw new IllegalArgumentException("File descriptors passed in Intent");
15839        }
15840
15841        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15842                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15843
15844        synchronized(this) {
15845            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15846                    != PackageManager.PERMISSION_GRANTED) {
15847                String msg = "Permission Denial: unbroadcastIntent() from pid="
15848                        + Binder.getCallingPid()
15849                        + ", uid=" + Binder.getCallingUid()
15850                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15851                Slog.w(TAG, msg);
15852                throw new SecurityException(msg);
15853            }
15854            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15855            if (stickies != null) {
15856                ArrayList<Intent> list = stickies.get(intent.getAction());
15857                if (list != null) {
15858                    int N = list.size();
15859                    int i;
15860                    for (i=0; i<N; i++) {
15861                        if (intent.filterEquals(list.get(i))) {
15862                            list.remove(i);
15863                            break;
15864                        }
15865                    }
15866                    if (list.size() <= 0) {
15867                        stickies.remove(intent.getAction());
15868                    }
15869                }
15870                if (stickies.size() <= 0) {
15871                    mStickyBroadcasts.remove(userId);
15872                }
15873            }
15874        }
15875    }
15876
15877    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15878            String resultData, Bundle resultExtras, boolean resultAbort) {
15879        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15880        if (r == null) {
15881            Slog.w(TAG, "finishReceiver called but not found on queue");
15882            return false;
15883        }
15884
15885        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15886    }
15887
15888    void backgroundServicesFinishedLocked(int userId) {
15889        for (BroadcastQueue queue : mBroadcastQueues) {
15890            queue.backgroundServicesFinishedLocked(userId);
15891        }
15892    }
15893
15894    public void finishReceiver(IBinder who, int resultCode, String resultData,
15895            Bundle resultExtras, boolean resultAbort) {
15896        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15897
15898        // Refuse possible leaked file descriptors
15899        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15900            throw new IllegalArgumentException("File descriptors passed in Bundle");
15901        }
15902
15903        final long origId = Binder.clearCallingIdentity();
15904        try {
15905            boolean doNext = false;
15906            BroadcastRecord r;
15907
15908            synchronized(this) {
15909                r = broadcastRecordForReceiverLocked(who);
15910                if (r != null) {
15911                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15912                        resultData, resultExtras, resultAbort, true);
15913                }
15914            }
15915
15916            if (doNext) {
15917                r.queue.processNextBroadcast(false);
15918            }
15919            trimApplications();
15920        } finally {
15921            Binder.restoreCallingIdentity(origId);
15922        }
15923    }
15924
15925    // =========================================================
15926    // INSTRUMENTATION
15927    // =========================================================
15928
15929    public boolean startInstrumentation(ComponentName className,
15930            String profileFile, int flags, Bundle arguments,
15931            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15932            int userId, String abiOverride) {
15933        enforceNotIsolatedCaller("startInstrumentation");
15934        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15935                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15936        // Refuse possible leaked file descriptors
15937        if (arguments != null && arguments.hasFileDescriptors()) {
15938            throw new IllegalArgumentException("File descriptors passed in Bundle");
15939        }
15940
15941        synchronized(this) {
15942            InstrumentationInfo ii = null;
15943            ApplicationInfo ai = null;
15944            try {
15945                ii = mContext.getPackageManager().getInstrumentationInfo(
15946                    className, STOCK_PM_FLAGS);
15947                ai = AppGlobals.getPackageManager().getApplicationInfo(
15948                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15949            } catch (PackageManager.NameNotFoundException e) {
15950            } catch (RemoteException e) {
15951            }
15952            if (ii == null) {
15953                reportStartInstrumentationFailure(watcher, className,
15954                        "Unable to find instrumentation info for: " + className);
15955                return false;
15956            }
15957            if (ai == null) {
15958                reportStartInstrumentationFailure(watcher, className,
15959                        "Unable to find instrumentation target package: " + ii.targetPackage);
15960                return false;
15961            }
15962
15963            int match = mContext.getPackageManager().checkSignatures(
15964                    ii.targetPackage, ii.packageName);
15965            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15966                String msg = "Permission Denial: starting instrumentation "
15967                        + className + " from pid="
15968                        + Binder.getCallingPid()
15969                        + ", uid=" + Binder.getCallingPid()
15970                        + " not allowed because package " + ii.packageName
15971                        + " does not have a signature matching the target "
15972                        + ii.targetPackage;
15973                reportStartInstrumentationFailure(watcher, className, msg);
15974                throw new SecurityException(msg);
15975            }
15976
15977            final long origId = Binder.clearCallingIdentity();
15978            // Instrumentation can kill and relaunch even persistent processes
15979            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15980                    "start instr");
15981            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15982            app.instrumentationClass = className;
15983            app.instrumentationInfo = ai;
15984            app.instrumentationProfileFile = profileFile;
15985            app.instrumentationArguments = arguments;
15986            app.instrumentationWatcher = watcher;
15987            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15988            app.instrumentationResultClass = className;
15989            Binder.restoreCallingIdentity(origId);
15990        }
15991
15992        return true;
15993    }
15994
15995    /**
15996     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15997     * error to the logs, but if somebody is watching, send the report there too.  This enables
15998     * the "am" command to report errors with more information.
15999     *
16000     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16001     * @param cn The component name of the instrumentation.
16002     * @param report The error report.
16003     */
16004    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16005            ComponentName cn, String report) {
16006        Slog.w(TAG, report);
16007        try {
16008            if (watcher != null) {
16009                Bundle results = new Bundle();
16010                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16011                results.putString("Error", report);
16012                watcher.instrumentationStatus(cn, -1, results);
16013            }
16014        } catch (RemoteException e) {
16015            Slog.w(TAG, e);
16016        }
16017    }
16018
16019    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16020        if (app.instrumentationWatcher != null) {
16021            try {
16022                // NOTE:  IInstrumentationWatcher *must* be oneway here
16023                app.instrumentationWatcher.instrumentationFinished(
16024                    app.instrumentationClass,
16025                    resultCode,
16026                    results);
16027            } catch (RemoteException e) {
16028            }
16029        }
16030        if (app.instrumentationUiAutomationConnection != null) {
16031            try {
16032                app.instrumentationUiAutomationConnection.shutdown();
16033            } catch (RemoteException re) {
16034                /* ignore */
16035            }
16036            // Only a UiAutomation can set this flag and now that
16037            // it is finished we make sure it is reset to its default.
16038            mUserIsMonkey = false;
16039        }
16040        app.instrumentationWatcher = null;
16041        app.instrumentationUiAutomationConnection = null;
16042        app.instrumentationClass = null;
16043        app.instrumentationInfo = null;
16044        app.instrumentationProfileFile = null;
16045        app.instrumentationArguments = null;
16046
16047        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16048                "finished inst");
16049    }
16050
16051    public void finishInstrumentation(IApplicationThread target,
16052            int resultCode, Bundle results) {
16053        int userId = UserHandle.getCallingUserId();
16054        // Refuse possible leaked file descriptors
16055        if (results != null && results.hasFileDescriptors()) {
16056            throw new IllegalArgumentException("File descriptors passed in Intent");
16057        }
16058
16059        synchronized(this) {
16060            ProcessRecord app = getRecordForAppLocked(target);
16061            if (app == null) {
16062                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16063                return;
16064            }
16065            final long origId = Binder.clearCallingIdentity();
16066            finishInstrumentationLocked(app, resultCode, results);
16067            Binder.restoreCallingIdentity(origId);
16068        }
16069    }
16070
16071    // =========================================================
16072    // CONFIGURATION
16073    // =========================================================
16074
16075    public ConfigurationInfo getDeviceConfigurationInfo() {
16076        ConfigurationInfo config = new ConfigurationInfo();
16077        synchronized (this) {
16078            config.reqTouchScreen = mConfiguration.touchscreen;
16079            config.reqKeyboardType = mConfiguration.keyboard;
16080            config.reqNavigation = mConfiguration.navigation;
16081            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16082                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16083                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16084            }
16085            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16086                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16087                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16088            }
16089            config.reqGlEsVersion = GL_ES_VERSION;
16090        }
16091        return config;
16092    }
16093
16094    ActivityStack getFocusedStack() {
16095        return mStackSupervisor.getFocusedStack();
16096    }
16097
16098    public Configuration getConfiguration() {
16099        Configuration ci;
16100        synchronized(this) {
16101            ci = new Configuration(mConfiguration);
16102        }
16103        return ci;
16104    }
16105
16106    public void updatePersistentConfiguration(Configuration values) {
16107        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16108                "updateConfiguration()");
16109        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16110                "updateConfiguration()");
16111        if (values == null) {
16112            throw new NullPointerException("Configuration must not be null");
16113        }
16114
16115        synchronized(this) {
16116            final long origId = Binder.clearCallingIdentity();
16117            updateConfigurationLocked(values, null, true, false);
16118            Binder.restoreCallingIdentity(origId);
16119        }
16120    }
16121
16122    public void updateConfiguration(Configuration values) {
16123        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16124                "updateConfiguration()");
16125
16126        synchronized(this) {
16127            if (values == null && mWindowManager != null) {
16128                // sentinel: fetch the current configuration from the window manager
16129                values = mWindowManager.computeNewConfiguration();
16130            }
16131
16132            if (mWindowManager != null) {
16133                mProcessList.applyDisplaySize(mWindowManager);
16134            }
16135
16136            final long origId = Binder.clearCallingIdentity();
16137            if (values != null) {
16138                Settings.System.clearConfiguration(values);
16139            }
16140            updateConfigurationLocked(values, null, false, false);
16141            Binder.restoreCallingIdentity(origId);
16142        }
16143    }
16144
16145    /**
16146     * Do either or both things: (1) change the current configuration, and (2)
16147     * make sure the given activity is running with the (now) current
16148     * configuration.  Returns true if the activity has been left running, or
16149     * false if <var>starting</var> is being destroyed to match the new
16150     * configuration.
16151     * @param persistent TODO
16152     */
16153    boolean updateConfigurationLocked(Configuration values,
16154            ActivityRecord starting, boolean persistent, boolean initLocale) {
16155        int changes = 0;
16156
16157        if (values != null) {
16158            Configuration newConfig = new Configuration(mConfiguration);
16159            changes = newConfig.updateFrom(values);
16160            if (changes != 0) {
16161                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16162                    Slog.i(TAG, "Updating configuration to: " + values);
16163                }
16164
16165                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16166
16167                if (values.locale != null && !initLocale) {
16168                    saveLocaleLocked(values.locale,
16169                                     !values.locale.equals(mConfiguration.locale),
16170                                     values.userSetLocale);
16171                }
16172
16173                mConfigurationSeq++;
16174                if (mConfigurationSeq <= 0) {
16175                    mConfigurationSeq = 1;
16176                }
16177                newConfig.seq = mConfigurationSeq;
16178                mConfiguration = newConfig;
16179                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16180                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16181                //mUsageStatsService.noteStartConfig(newConfig);
16182
16183                final Configuration configCopy = new Configuration(mConfiguration);
16184
16185                // TODO: If our config changes, should we auto dismiss any currently
16186                // showing dialogs?
16187                mShowDialogs = shouldShowDialogs(newConfig);
16188
16189                AttributeCache ac = AttributeCache.instance();
16190                if (ac != null) {
16191                    ac.updateConfiguration(configCopy);
16192                }
16193
16194                // Make sure all resources in our process are updated
16195                // right now, so that anyone who is going to retrieve
16196                // resource values after we return will be sure to get
16197                // the new ones.  This is especially important during
16198                // boot, where the first config change needs to guarantee
16199                // all resources have that config before following boot
16200                // code is executed.
16201                mSystemThread.applyConfigurationToResources(configCopy);
16202
16203                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16204                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16205                    msg.obj = new Configuration(configCopy);
16206                    mHandler.sendMessage(msg);
16207                }
16208
16209                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16210                    ProcessRecord app = mLruProcesses.get(i);
16211                    try {
16212                        if (app.thread != null) {
16213                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16214                                    + app.processName + " new config " + mConfiguration);
16215                            app.thread.scheduleConfigurationChanged(configCopy);
16216                        }
16217                    } catch (Exception e) {
16218                    }
16219                }
16220                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16221                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16222                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16223                        | Intent.FLAG_RECEIVER_FOREGROUND);
16224                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16225                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16226                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16227                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16228                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16229                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16230                    broadcastIntentLocked(null, null, intent,
16231                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16232                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16233                }
16234            }
16235        }
16236
16237        boolean kept = true;
16238        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16239        // mainStack is null during startup.
16240        if (mainStack != null) {
16241            if (changes != 0 && starting == null) {
16242                // If the configuration changed, and the caller is not already
16243                // in the process of starting an activity, then find the top
16244                // activity to check if its configuration needs to change.
16245                starting = mainStack.topRunningActivityLocked(null);
16246            }
16247
16248            if (starting != null) {
16249                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16250                // And we need to make sure at this point that all other activities
16251                // are made visible with the correct configuration.
16252                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16253            }
16254        }
16255
16256        if (values != null && mWindowManager != null) {
16257            mWindowManager.setNewConfiguration(mConfiguration);
16258        }
16259
16260        return kept;
16261    }
16262
16263    /**
16264     * Decide based on the configuration whether we should shouw the ANR,
16265     * crash, etc dialogs.  The idea is that if there is no affordnace to
16266     * press the on-screen buttons, we shouldn't show the dialog.
16267     *
16268     * A thought: SystemUI might also want to get told about this, the Power
16269     * dialog / global actions also might want different behaviors.
16270     */
16271    private static final boolean shouldShowDialogs(Configuration config) {
16272        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16273                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16274    }
16275
16276    /**
16277     * Save the locale.  You must be inside a synchronized (this) block.
16278     */
16279    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16280        if(isDiff) {
16281            SystemProperties.set("user.language", l.getLanguage());
16282            SystemProperties.set("user.region", l.getCountry());
16283        }
16284
16285        if(isPersist) {
16286            SystemProperties.set("persist.sys.language", l.getLanguage());
16287            SystemProperties.set("persist.sys.country", l.getCountry());
16288            SystemProperties.set("persist.sys.localevar", l.getVariant());
16289
16290            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16291        }
16292    }
16293
16294    @Override
16295    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16296        synchronized (this) {
16297            ActivityRecord srec = ActivityRecord.forToken(token);
16298            if (srec.task != null && srec.task.stack != null) {
16299                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16300            }
16301        }
16302        return false;
16303    }
16304
16305    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16306            Intent resultData) {
16307
16308        synchronized (this) {
16309            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16310            if (stack != null) {
16311                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16312            }
16313            return false;
16314        }
16315    }
16316
16317    public int getLaunchedFromUid(IBinder activityToken) {
16318        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16319        if (srec == null) {
16320            return -1;
16321        }
16322        return srec.launchedFromUid;
16323    }
16324
16325    public String getLaunchedFromPackage(IBinder activityToken) {
16326        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16327        if (srec == null) {
16328            return null;
16329        }
16330        return srec.launchedFromPackage;
16331    }
16332
16333    // =========================================================
16334    // LIFETIME MANAGEMENT
16335    // =========================================================
16336
16337    // Returns which broadcast queue the app is the current [or imminent] receiver
16338    // on, or 'null' if the app is not an active broadcast recipient.
16339    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16340        BroadcastRecord r = app.curReceiver;
16341        if (r != null) {
16342            return r.queue;
16343        }
16344
16345        // It's not the current receiver, but it might be starting up to become one
16346        synchronized (this) {
16347            for (BroadcastQueue queue : mBroadcastQueues) {
16348                r = queue.mPendingBroadcast;
16349                if (r != null && r.curApp == app) {
16350                    // found it; report which queue it's in
16351                    return queue;
16352                }
16353            }
16354        }
16355
16356        return null;
16357    }
16358
16359    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16360            boolean doingAll, long now) {
16361        if (mAdjSeq == app.adjSeq) {
16362            // This adjustment has already been computed.
16363            return app.curRawAdj;
16364        }
16365
16366        if (app.thread == null) {
16367            app.adjSeq = mAdjSeq;
16368            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16369            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16370            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16371        }
16372
16373        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16374        app.adjSource = null;
16375        app.adjTarget = null;
16376        app.empty = false;
16377        app.cached = false;
16378
16379        final int activitiesSize = app.activities.size();
16380
16381        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16382            // The max adjustment doesn't allow this app to be anything
16383            // below foreground, so it is not worth doing work for it.
16384            app.adjType = "fixed";
16385            app.adjSeq = mAdjSeq;
16386            app.curRawAdj = app.maxAdj;
16387            app.foregroundActivities = false;
16388            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16389            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16390            // System processes can do UI, and when they do we want to have
16391            // them trim their memory after the user leaves the UI.  To
16392            // facilitate this, here we need to determine whether or not it
16393            // is currently showing UI.
16394            app.systemNoUi = true;
16395            if (app == TOP_APP) {
16396                app.systemNoUi = false;
16397            } else if (activitiesSize > 0) {
16398                for (int j = 0; j < activitiesSize; j++) {
16399                    final ActivityRecord r = app.activities.get(j);
16400                    if (r.visible) {
16401                        app.systemNoUi = false;
16402                    }
16403                }
16404            }
16405            if (!app.systemNoUi) {
16406                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16407            }
16408            return (app.curAdj=app.maxAdj);
16409        }
16410
16411        app.systemNoUi = false;
16412
16413        // Determine the importance of the process, starting with most
16414        // important to least, and assign an appropriate OOM adjustment.
16415        int adj;
16416        int schedGroup;
16417        int procState;
16418        boolean foregroundActivities = false;
16419        BroadcastQueue queue;
16420        if (app == TOP_APP) {
16421            // The last app on the list is the foreground app.
16422            adj = ProcessList.FOREGROUND_APP_ADJ;
16423            schedGroup = Process.THREAD_GROUP_DEFAULT;
16424            app.adjType = "top-activity";
16425            foregroundActivities = true;
16426            procState = ActivityManager.PROCESS_STATE_TOP;
16427        } else if (app.instrumentationClass != null) {
16428            // Don't want to kill running instrumentation.
16429            adj = ProcessList.FOREGROUND_APP_ADJ;
16430            schedGroup = Process.THREAD_GROUP_DEFAULT;
16431            app.adjType = "instrumentation";
16432            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16433        } else if ((queue = isReceivingBroadcast(app)) != null) {
16434            // An app that is currently receiving a broadcast also
16435            // counts as being in the foreground for OOM killer purposes.
16436            // It's placed in a sched group based on the nature of the
16437            // broadcast as reflected by which queue it's active in.
16438            adj = ProcessList.FOREGROUND_APP_ADJ;
16439            schedGroup = (queue == mFgBroadcastQueue)
16440                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16441            app.adjType = "broadcast";
16442            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16443        } else if (app.executingServices.size() > 0) {
16444            // An app that is currently executing a service callback also
16445            // counts as being in the foreground.
16446            adj = ProcessList.FOREGROUND_APP_ADJ;
16447            schedGroup = app.execServicesFg ?
16448                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16449            app.adjType = "exec-service";
16450            procState = ActivityManager.PROCESS_STATE_SERVICE;
16451            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16452        } else {
16453            // As far as we know the process is empty.  We may change our mind later.
16454            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16455            // At this point we don't actually know the adjustment.  Use the cached adj
16456            // value that the caller wants us to.
16457            adj = cachedAdj;
16458            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16459            app.cached = true;
16460            app.empty = true;
16461            app.adjType = "cch-empty";
16462        }
16463
16464        // Examine all activities if not already foreground.
16465        if (!foregroundActivities && activitiesSize > 0) {
16466            for (int j = 0; j < activitiesSize; j++) {
16467                final ActivityRecord r = app.activities.get(j);
16468                if (r.app != app) {
16469                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16470                            + app + "?!?");
16471                    continue;
16472                }
16473                if (r.visible) {
16474                    // App has a visible activity; only upgrade adjustment.
16475                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16476                        adj = ProcessList.VISIBLE_APP_ADJ;
16477                        app.adjType = "visible";
16478                    }
16479                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16480                        procState = ActivityManager.PROCESS_STATE_TOP;
16481                    }
16482                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16483                    app.cached = false;
16484                    app.empty = false;
16485                    foregroundActivities = true;
16486                    break;
16487                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16488                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16489                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16490                        app.adjType = "pausing";
16491                    }
16492                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16493                        procState = ActivityManager.PROCESS_STATE_TOP;
16494                    }
16495                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16496                    app.cached = false;
16497                    app.empty = false;
16498                    foregroundActivities = true;
16499                } else if (r.state == ActivityState.STOPPING) {
16500                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16501                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16502                        app.adjType = "stopping";
16503                    }
16504                    // For the process state, we will at this point consider the
16505                    // process to be cached.  It will be cached either as an activity
16506                    // or empty depending on whether the activity is finishing.  We do
16507                    // this so that we can treat the process as cached for purposes of
16508                    // memory trimming (determing current memory level, trim command to
16509                    // send to process) since there can be an arbitrary number of stopping
16510                    // processes and they should soon all go into the cached state.
16511                    if (!r.finishing) {
16512                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16513                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16514                        }
16515                    }
16516                    app.cached = false;
16517                    app.empty = false;
16518                    foregroundActivities = true;
16519                } else {
16520                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16521                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16522                        app.adjType = "cch-act";
16523                    }
16524                }
16525            }
16526        }
16527
16528        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16529            if (app.foregroundServices) {
16530                // The user is aware of this app, so make it visible.
16531                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16532                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16533                app.cached = false;
16534                app.adjType = "fg-service";
16535                schedGroup = Process.THREAD_GROUP_DEFAULT;
16536            } else if (app.forcingToForeground != null) {
16537                // The user is aware of this app, so make it visible.
16538                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16539                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16540                app.cached = false;
16541                app.adjType = "force-fg";
16542                app.adjSource = app.forcingToForeground;
16543                schedGroup = Process.THREAD_GROUP_DEFAULT;
16544            }
16545        }
16546
16547        if (app == mHeavyWeightProcess) {
16548            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16549                // We don't want to kill the current heavy-weight process.
16550                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16551                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16552                app.cached = false;
16553                app.adjType = "heavy";
16554            }
16555            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16556                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16557            }
16558        }
16559
16560        if (app == mHomeProcess) {
16561            if (adj > ProcessList.HOME_APP_ADJ) {
16562                // This process is hosting what we currently consider to be the
16563                // home app, so we don't want to let it go into the background.
16564                adj = ProcessList.HOME_APP_ADJ;
16565                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16566                app.cached = false;
16567                app.adjType = "home";
16568            }
16569            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16570                procState = ActivityManager.PROCESS_STATE_HOME;
16571            }
16572        }
16573
16574        if (app == mPreviousProcess && app.activities.size() > 0) {
16575            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16576                // This was the previous process that showed UI to the user.
16577                // We want to try to keep it around more aggressively, to give
16578                // a good experience around switching between two apps.
16579                adj = ProcessList.PREVIOUS_APP_ADJ;
16580                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16581                app.cached = false;
16582                app.adjType = "previous";
16583            }
16584            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16585                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16586            }
16587        }
16588
16589        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16590                + " reason=" + app.adjType);
16591
16592        // By default, we use the computed adjustment.  It may be changed if
16593        // there are applications dependent on our services or providers, but
16594        // this gives us a baseline and makes sure we don't get into an
16595        // infinite recursion.
16596        app.adjSeq = mAdjSeq;
16597        app.curRawAdj = adj;
16598        app.hasStartedServices = false;
16599
16600        if (mBackupTarget != null && app == mBackupTarget.app) {
16601            // If possible we want to avoid killing apps while they're being backed up
16602            if (adj > ProcessList.BACKUP_APP_ADJ) {
16603                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16604                adj = ProcessList.BACKUP_APP_ADJ;
16605                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16606                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16607                }
16608                app.adjType = "backup";
16609                app.cached = false;
16610            }
16611            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16612                procState = ActivityManager.PROCESS_STATE_BACKUP;
16613            }
16614        }
16615
16616        boolean mayBeTop = false;
16617
16618        for (int is = app.services.size()-1;
16619                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16620                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16621                        || procState > ActivityManager.PROCESS_STATE_TOP);
16622                is--) {
16623            ServiceRecord s = app.services.valueAt(is);
16624            if (s.startRequested) {
16625                app.hasStartedServices = true;
16626                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16627                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16628                }
16629                if (app.hasShownUi && app != mHomeProcess) {
16630                    // If this process has shown some UI, let it immediately
16631                    // go to the LRU list because it may be pretty heavy with
16632                    // UI stuff.  We'll tag it with a label just to help
16633                    // debug and understand what is going on.
16634                    if (adj > ProcessList.SERVICE_ADJ) {
16635                        app.adjType = "cch-started-ui-services";
16636                    }
16637                } else {
16638                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16639                        // This service has seen some activity within
16640                        // recent memory, so we will keep its process ahead
16641                        // of the background processes.
16642                        if (adj > ProcessList.SERVICE_ADJ) {
16643                            adj = ProcessList.SERVICE_ADJ;
16644                            app.adjType = "started-services";
16645                            app.cached = false;
16646                        }
16647                    }
16648                    // If we have let the service slide into the background
16649                    // state, still have some text describing what it is doing
16650                    // even though the service no longer has an impact.
16651                    if (adj > ProcessList.SERVICE_ADJ) {
16652                        app.adjType = "cch-started-services";
16653                    }
16654                }
16655            }
16656            for (int conni = s.connections.size()-1;
16657                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16658                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16659                            || procState > ActivityManager.PROCESS_STATE_TOP);
16660                    conni--) {
16661                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16662                for (int i = 0;
16663                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16664                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16665                                || procState > ActivityManager.PROCESS_STATE_TOP);
16666                        i++) {
16667                    // XXX should compute this based on the max of
16668                    // all connected clients.
16669                    ConnectionRecord cr = clist.get(i);
16670                    if (cr.binding.client == app) {
16671                        // Binding to ourself is not interesting.
16672                        continue;
16673                    }
16674                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16675                        ProcessRecord client = cr.binding.client;
16676                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16677                                TOP_APP, doingAll, now);
16678                        int clientProcState = client.curProcState;
16679                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16680                            // If the other app is cached for any reason, for purposes here
16681                            // we are going to consider it empty.  The specific cached state
16682                            // doesn't propagate except under certain conditions.
16683                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16684                        }
16685                        String adjType = null;
16686                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16687                            // Not doing bind OOM management, so treat
16688                            // this guy more like a started service.
16689                            if (app.hasShownUi && app != mHomeProcess) {
16690                                // If this process has shown some UI, let it immediately
16691                                // go to the LRU list because it may be pretty heavy with
16692                                // UI stuff.  We'll tag it with a label just to help
16693                                // debug and understand what is going on.
16694                                if (adj > clientAdj) {
16695                                    adjType = "cch-bound-ui-services";
16696                                }
16697                                app.cached = false;
16698                                clientAdj = adj;
16699                                clientProcState = procState;
16700                            } else {
16701                                if (now >= (s.lastActivity
16702                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16703                                    // This service has not seen activity within
16704                                    // recent memory, so allow it to drop to the
16705                                    // LRU list if there is no other reason to keep
16706                                    // it around.  We'll also tag it with a label just
16707                                    // to help debug and undertand what is going on.
16708                                    if (adj > clientAdj) {
16709                                        adjType = "cch-bound-services";
16710                                    }
16711                                    clientAdj = adj;
16712                                }
16713                            }
16714                        }
16715                        if (adj > clientAdj) {
16716                            // If this process has recently shown UI, and
16717                            // the process that is binding to it is less
16718                            // important than being visible, then we don't
16719                            // care about the binding as much as we care
16720                            // about letting this process get into the LRU
16721                            // list to be killed and restarted if needed for
16722                            // memory.
16723                            if (app.hasShownUi && app != mHomeProcess
16724                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16725                                adjType = "cch-bound-ui-services";
16726                            } else {
16727                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16728                                        |Context.BIND_IMPORTANT)) != 0) {
16729                                    adj = clientAdj;
16730                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16731                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16732                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16733                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16734                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16735                                    adj = clientAdj;
16736                                } else {
16737                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16738                                        adj = ProcessList.VISIBLE_APP_ADJ;
16739                                    }
16740                                }
16741                                if (!client.cached) {
16742                                    app.cached = false;
16743                                }
16744                                adjType = "service";
16745                            }
16746                        }
16747                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16748                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16749                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16750                            }
16751                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16752                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16753                                    // Special handling of clients who are in the top state.
16754                                    // We *may* want to consider this process to be in the
16755                                    // top state as well, but only if there is not another
16756                                    // reason for it to be running.  Being on the top is a
16757                                    // special state, meaning you are specifically running
16758                                    // for the current top app.  If the process is already
16759                                    // running in the background for some other reason, it
16760                                    // is more important to continue considering it to be
16761                                    // in the background state.
16762                                    mayBeTop = true;
16763                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16764                                } else {
16765                                    // Special handling for above-top states (persistent
16766                                    // processes).  These should not bring the current process
16767                                    // into the top state, since they are not on top.  Instead
16768                                    // give them the best state after that.
16769                                    clientProcState =
16770                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16771                                }
16772                            }
16773                        } else {
16774                            if (clientProcState <
16775                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16776                                clientProcState =
16777                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16778                            }
16779                        }
16780                        if (procState > clientProcState) {
16781                            procState = clientProcState;
16782                        }
16783                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16784                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16785                            app.pendingUiClean = true;
16786                        }
16787                        if (adjType != null) {
16788                            app.adjType = adjType;
16789                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16790                                    .REASON_SERVICE_IN_USE;
16791                            app.adjSource = cr.binding.client;
16792                            app.adjSourceProcState = clientProcState;
16793                            app.adjTarget = s.name;
16794                        }
16795                    }
16796                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16797                        app.treatLikeActivity = true;
16798                    }
16799                    final ActivityRecord a = cr.activity;
16800                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16801                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16802                                (a.visible || a.state == ActivityState.RESUMED
16803                                 || a.state == ActivityState.PAUSING)) {
16804                            adj = ProcessList.FOREGROUND_APP_ADJ;
16805                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16806                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16807                            }
16808                            app.cached = false;
16809                            app.adjType = "service";
16810                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16811                                    .REASON_SERVICE_IN_USE;
16812                            app.adjSource = a;
16813                            app.adjSourceProcState = procState;
16814                            app.adjTarget = s.name;
16815                        }
16816                    }
16817                }
16818            }
16819        }
16820
16821        for (int provi = app.pubProviders.size()-1;
16822                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16823                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16824                        || procState > ActivityManager.PROCESS_STATE_TOP);
16825                provi--) {
16826            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16827            for (int i = cpr.connections.size()-1;
16828                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16829                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16830                            || procState > ActivityManager.PROCESS_STATE_TOP);
16831                    i--) {
16832                ContentProviderConnection conn = cpr.connections.get(i);
16833                ProcessRecord client = conn.client;
16834                if (client == app) {
16835                    // Being our own client is not interesting.
16836                    continue;
16837                }
16838                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16839                int clientProcState = client.curProcState;
16840                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16841                    // If the other app is cached for any reason, for purposes here
16842                    // we are going to consider it empty.
16843                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16844                }
16845                if (adj > clientAdj) {
16846                    if (app.hasShownUi && app != mHomeProcess
16847                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16848                        app.adjType = "cch-ui-provider";
16849                    } else {
16850                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16851                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16852                        app.adjType = "provider";
16853                    }
16854                    app.cached &= client.cached;
16855                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16856                            .REASON_PROVIDER_IN_USE;
16857                    app.adjSource = client;
16858                    app.adjSourceProcState = clientProcState;
16859                    app.adjTarget = cpr.name;
16860                }
16861                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16862                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16863                        // Special handling of clients who are in the top state.
16864                        // We *may* want to consider this process to be in the
16865                        // top state as well, but only if there is not another
16866                        // reason for it to be running.  Being on the top is a
16867                        // special state, meaning you are specifically running
16868                        // for the current top app.  If the process is already
16869                        // running in the background for some other reason, it
16870                        // is more important to continue considering it to be
16871                        // in the background state.
16872                        mayBeTop = true;
16873                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16874                    } else {
16875                        // Special handling for above-top states (persistent
16876                        // processes).  These should not bring the current process
16877                        // into the top state, since they are not on top.  Instead
16878                        // give them the best state after that.
16879                        clientProcState =
16880                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16881                    }
16882                }
16883                if (procState > clientProcState) {
16884                    procState = clientProcState;
16885                }
16886                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16887                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16888                }
16889            }
16890            // If the provider has external (non-framework) process
16891            // dependencies, ensure that its adjustment is at least
16892            // FOREGROUND_APP_ADJ.
16893            if (cpr.hasExternalProcessHandles()) {
16894                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16895                    adj = ProcessList.FOREGROUND_APP_ADJ;
16896                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16897                    app.cached = false;
16898                    app.adjType = "provider";
16899                    app.adjTarget = cpr.name;
16900                }
16901                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16902                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16903                }
16904            }
16905        }
16906
16907        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16908            // A client of one of our services or providers is in the top state.  We
16909            // *may* want to be in the top state, but not if we are already running in
16910            // the background for some other reason.  For the decision here, we are going
16911            // to pick out a few specific states that we want to remain in when a client
16912            // is top (states that tend to be longer-term) and otherwise allow it to go
16913            // to the top state.
16914            switch (procState) {
16915                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16916                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16917                case ActivityManager.PROCESS_STATE_SERVICE:
16918                    // These all are longer-term states, so pull them up to the top
16919                    // of the background states, but not all the way to the top state.
16920                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16921                    break;
16922                default:
16923                    // Otherwise, top is a better choice, so take it.
16924                    procState = ActivityManager.PROCESS_STATE_TOP;
16925                    break;
16926            }
16927        }
16928
16929        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16930            if (app.hasClientActivities) {
16931                // This is a cached process, but with client activities.  Mark it so.
16932                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16933                app.adjType = "cch-client-act";
16934            } else if (app.treatLikeActivity) {
16935                // This is a cached process, but somebody wants us to treat it like it has
16936                // an activity, okay!
16937                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16938                app.adjType = "cch-as-act";
16939            }
16940        }
16941
16942        if (adj == ProcessList.SERVICE_ADJ) {
16943            if (doingAll) {
16944                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16945                mNewNumServiceProcs++;
16946                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16947                if (!app.serviceb) {
16948                    // This service isn't far enough down on the LRU list to
16949                    // normally be a B service, but if we are low on RAM and it
16950                    // is large we want to force it down since we would prefer to
16951                    // keep launcher over it.
16952                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16953                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16954                        app.serviceHighRam = true;
16955                        app.serviceb = true;
16956                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16957                    } else {
16958                        mNewNumAServiceProcs++;
16959                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16960                    }
16961                } else {
16962                    app.serviceHighRam = false;
16963                }
16964            }
16965            if (app.serviceb) {
16966                adj = ProcessList.SERVICE_B_ADJ;
16967            }
16968        }
16969
16970        app.curRawAdj = adj;
16971
16972        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16973        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16974        if (adj > app.maxAdj) {
16975            adj = app.maxAdj;
16976            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16977                schedGroup = Process.THREAD_GROUP_DEFAULT;
16978            }
16979        }
16980
16981        // Do final modification to adj.  Everything we do between here and applying
16982        // the final setAdj must be done in this function, because we will also use
16983        // it when computing the final cached adj later.  Note that we don't need to
16984        // worry about this for max adj above, since max adj will always be used to
16985        // keep it out of the cached vaues.
16986        app.curAdj = app.modifyRawOomAdj(adj);
16987        app.curSchedGroup = schedGroup;
16988        app.curProcState = procState;
16989        app.foregroundActivities = foregroundActivities;
16990
16991        return app.curRawAdj;
16992    }
16993
16994    /**
16995     * Schedule PSS collection of a process.
16996     */
16997    void requestPssLocked(ProcessRecord proc, int procState) {
16998        if (mPendingPssProcesses.contains(proc)) {
16999            return;
17000        }
17001        if (mPendingPssProcesses.size() == 0) {
17002            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17003        }
17004        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17005        proc.pssProcState = procState;
17006        mPendingPssProcesses.add(proc);
17007    }
17008
17009    /**
17010     * Schedule PSS collection of all processes.
17011     */
17012    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17013        if (!always) {
17014            if (now < (mLastFullPssTime +
17015                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17016                return;
17017            }
17018        }
17019        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17020        mLastFullPssTime = now;
17021        mFullPssPending = true;
17022        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17023        mPendingPssProcesses.clear();
17024        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17025            ProcessRecord app = mLruProcesses.get(i);
17026            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17027                app.pssProcState = app.setProcState;
17028                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17029                        isSleeping(), now);
17030                mPendingPssProcesses.add(app);
17031            }
17032        }
17033        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17034    }
17035
17036    /**
17037     * Ask a given process to GC right now.
17038     */
17039    final void performAppGcLocked(ProcessRecord app) {
17040        try {
17041            app.lastRequestedGc = SystemClock.uptimeMillis();
17042            if (app.thread != null) {
17043                if (app.reportLowMemory) {
17044                    app.reportLowMemory = false;
17045                    app.thread.scheduleLowMemory();
17046                } else {
17047                    app.thread.processInBackground();
17048                }
17049            }
17050        } catch (Exception e) {
17051            // whatever.
17052        }
17053    }
17054
17055    /**
17056     * Returns true if things are idle enough to perform GCs.
17057     */
17058    private final boolean canGcNowLocked() {
17059        boolean processingBroadcasts = false;
17060        for (BroadcastQueue q : mBroadcastQueues) {
17061            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17062                processingBroadcasts = true;
17063            }
17064        }
17065        return !processingBroadcasts
17066                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17067    }
17068
17069    /**
17070     * Perform GCs on all processes that are waiting for it, but only
17071     * if things are idle.
17072     */
17073    final void performAppGcsLocked() {
17074        final int N = mProcessesToGc.size();
17075        if (N <= 0) {
17076            return;
17077        }
17078        if (canGcNowLocked()) {
17079            while (mProcessesToGc.size() > 0) {
17080                ProcessRecord proc = mProcessesToGc.remove(0);
17081                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17082                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17083                            <= SystemClock.uptimeMillis()) {
17084                        // To avoid spamming the system, we will GC processes one
17085                        // at a time, waiting a few seconds between each.
17086                        performAppGcLocked(proc);
17087                        scheduleAppGcsLocked();
17088                        return;
17089                    } else {
17090                        // It hasn't been long enough since we last GCed this
17091                        // process...  put it in the list to wait for its time.
17092                        addProcessToGcListLocked(proc);
17093                        break;
17094                    }
17095                }
17096            }
17097
17098            scheduleAppGcsLocked();
17099        }
17100    }
17101
17102    /**
17103     * If all looks good, perform GCs on all processes waiting for them.
17104     */
17105    final void performAppGcsIfAppropriateLocked() {
17106        if (canGcNowLocked()) {
17107            performAppGcsLocked();
17108            return;
17109        }
17110        // Still not idle, wait some more.
17111        scheduleAppGcsLocked();
17112    }
17113
17114    /**
17115     * Schedule the execution of all pending app GCs.
17116     */
17117    final void scheduleAppGcsLocked() {
17118        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17119
17120        if (mProcessesToGc.size() > 0) {
17121            // Schedule a GC for the time to the next process.
17122            ProcessRecord proc = mProcessesToGc.get(0);
17123            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17124
17125            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17126            long now = SystemClock.uptimeMillis();
17127            if (when < (now+GC_TIMEOUT)) {
17128                when = now + GC_TIMEOUT;
17129            }
17130            mHandler.sendMessageAtTime(msg, when);
17131        }
17132    }
17133
17134    /**
17135     * Add a process to the array of processes waiting to be GCed.  Keeps the
17136     * list in sorted order by the last GC time.  The process can't already be
17137     * on the list.
17138     */
17139    final void addProcessToGcListLocked(ProcessRecord proc) {
17140        boolean added = false;
17141        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17142            if (mProcessesToGc.get(i).lastRequestedGc <
17143                    proc.lastRequestedGc) {
17144                added = true;
17145                mProcessesToGc.add(i+1, proc);
17146                break;
17147            }
17148        }
17149        if (!added) {
17150            mProcessesToGc.add(0, proc);
17151        }
17152    }
17153
17154    /**
17155     * Set up to ask a process to GC itself.  This will either do it
17156     * immediately, or put it on the list of processes to gc the next
17157     * time things are idle.
17158     */
17159    final void scheduleAppGcLocked(ProcessRecord app) {
17160        long now = SystemClock.uptimeMillis();
17161        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17162            return;
17163        }
17164        if (!mProcessesToGc.contains(app)) {
17165            addProcessToGcListLocked(app);
17166            scheduleAppGcsLocked();
17167        }
17168    }
17169
17170    final void checkExcessivePowerUsageLocked(boolean doKills) {
17171        updateCpuStatsNow();
17172
17173        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17174        boolean doWakeKills = doKills;
17175        boolean doCpuKills = doKills;
17176        if (mLastPowerCheckRealtime == 0) {
17177            doWakeKills = false;
17178        }
17179        if (mLastPowerCheckUptime == 0) {
17180            doCpuKills = false;
17181        }
17182        if (stats.isScreenOn()) {
17183            doWakeKills = false;
17184        }
17185        final long curRealtime = SystemClock.elapsedRealtime();
17186        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17187        final long curUptime = SystemClock.uptimeMillis();
17188        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17189        mLastPowerCheckRealtime = curRealtime;
17190        mLastPowerCheckUptime = curUptime;
17191        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17192            doWakeKills = false;
17193        }
17194        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17195            doCpuKills = false;
17196        }
17197        int i = mLruProcesses.size();
17198        while (i > 0) {
17199            i--;
17200            ProcessRecord app = mLruProcesses.get(i);
17201            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17202                long wtime;
17203                synchronized (stats) {
17204                    wtime = stats.getProcessWakeTime(app.info.uid,
17205                            app.pid, curRealtime);
17206                }
17207                long wtimeUsed = wtime - app.lastWakeTime;
17208                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17209                if (DEBUG_POWER) {
17210                    StringBuilder sb = new StringBuilder(128);
17211                    sb.append("Wake for ");
17212                    app.toShortString(sb);
17213                    sb.append(": over ");
17214                    TimeUtils.formatDuration(realtimeSince, sb);
17215                    sb.append(" used ");
17216                    TimeUtils.formatDuration(wtimeUsed, sb);
17217                    sb.append(" (");
17218                    sb.append((wtimeUsed*100)/realtimeSince);
17219                    sb.append("%)");
17220                    Slog.i(TAG, sb.toString());
17221                    sb.setLength(0);
17222                    sb.append("CPU for ");
17223                    app.toShortString(sb);
17224                    sb.append(": over ");
17225                    TimeUtils.formatDuration(uptimeSince, sb);
17226                    sb.append(" used ");
17227                    TimeUtils.formatDuration(cputimeUsed, sb);
17228                    sb.append(" (");
17229                    sb.append((cputimeUsed*100)/uptimeSince);
17230                    sb.append("%)");
17231                    Slog.i(TAG, sb.toString());
17232                }
17233                // If a process has held a wake lock for more
17234                // than 50% of the time during this period,
17235                // that sounds bad.  Kill!
17236                if (doWakeKills && realtimeSince > 0
17237                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17238                    synchronized (stats) {
17239                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17240                                realtimeSince, wtimeUsed);
17241                    }
17242                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17243                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17244                } else if (doCpuKills && uptimeSince > 0
17245                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17246                    synchronized (stats) {
17247                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17248                                uptimeSince, cputimeUsed);
17249                    }
17250                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17251                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17252                } else {
17253                    app.lastWakeTime = wtime;
17254                    app.lastCpuTime = app.curCpuTime;
17255                }
17256            }
17257        }
17258    }
17259
17260    private final boolean applyOomAdjLocked(ProcessRecord app,
17261            ProcessRecord TOP_APP, boolean doingAll, long now) {
17262        boolean success = true;
17263
17264        if (app.curRawAdj != app.setRawAdj) {
17265            app.setRawAdj = app.curRawAdj;
17266        }
17267
17268        int changes = 0;
17269
17270        if (app.curAdj != app.setAdj) {
17271            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17272            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17273                TAG, "Set " + app.pid + " " + app.processName +
17274                " adj " + app.curAdj + ": " + app.adjType);
17275            app.setAdj = app.curAdj;
17276        }
17277
17278        if (app.setSchedGroup != app.curSchedGroup) {
17279            app.setSchedGroup = app.curSchedGroup;
17280            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17281                    "Setting process group of " + app.processName
17282                    + " to " + app.curSchedGroup);
17283            if (app.waitingToKill != null &&
17284                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17285                app.kill(app.waitingToKill, true);
17286                success = false;
17287            } else {
17288                if (true) {
17289                    long oldId = Binder.clearCallingIdentity();
17290                    try {
17291                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17292                    } catch (Exception e) {
17293                        Slog.w(TAG, "Failed setting process group of " + app.pid
17294                                + " to " + app.curSchedGroup);
17295                        e.printStackTrace();
17296                    } finally {
17297                        Binder.restoreCallingIdentity(oldId);
17298                    }
17299                } else {
17300                    if (app.thread != null) {
17301                        try {
17302                            app.thread.setSchedulingGroup(app.curSchedGroup);
17303                        } catch (RemoteException e) {
17304                        }
17305                    }
17306                }
17307                Process.setSwappiness(app.pid,
17308                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17309            }
17310        }
17311        if (app.repForegroundActivities != app.foregroundActivities) {
17312            app.repForegroundActivities = app.foregroundActivities;
17313            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17314        }
17315        if (app.repProcState != app.curProcState) {
17316            app.repProcState = app.curProcState;
17317            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17318            if (app.thread != null) {
17319                try {
17320                    if (false) {
17321                        //RuntimeException h = new RuntimeException("here");
17322                        Slog.i(TAG, "Sending new process state " + app.repProcState
17323                                + " to " + app /*, h*/);
17324                    }
17325                    app.thread.setProcessState(app.repProcState);
17326                } catch (RemoteException e) {
17327                }
17328            }
17329        }
17330        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17331                app.setProcState)) {
17332            app.lastStateTime = now;
17333            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17334                    isSleeping(), now);
17335            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17336                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17337                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17338                    + (app.nextPssTime-now) + ": " + app);
17339        } else {
17340            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17341                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17342                requestPssLocked(app, app.setProcState);
17343                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17344                        isSleeping(), now);
17345            } else if (false && DEBUG_PSS) {
17346                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17347            }
17348        }
17349        if (app.setProcState != app.curProcState) {
17350            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17351                    "Proc state change of " + app.processName
17352                    + " to " + app.curProcState);
17353            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17354            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17355            if (setImportant && !curImportant) {
17356                // This app is no longer something we consider important enough to allow to
17357                // use arbitrary amounts of battery power.  Note
17358                // its current wake lock time to later know to kill it if
17359                // it is not behaving well.
17360                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17361                synchronized (stats) {
17362                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17363                            app.pid, SystemClock.elapsedRealtime());
17364                }
17365                app.lastCpuTime = app.curCpuTime;
17366
17367            }
17368            app.setProcState = app.curProcState;
17369            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17370                app.notCachedSinceIdle = false;
17371            }
17372            if (!doingAll) {
17373                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17374            } else {
17375                app.procStateChanged = true;
17376            }
17377        }
17378
17379        if (changes != 0) {
17380            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17381            int i = mPendingProcessChanges.size()-1;
17382            ProcessChangeItem item = null;
17383            while (i >= 0) {
17384                item = mPendingProcessChanges.get(i);
17385                if (item.pid == app.pid) {
17386                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17387                    break;
17388                }
17389                i--;
17390            }
17391            if (i < 0) {
17392                // No existing item in pending changes; need a new one.
17393                final int NA = mAvailProcessChanges.size();
17394                if (NA > 0) {
17395                    item = mAvailProcessChanges.remove(NA-1);
17396                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17397                } else {
17398                    item = new ProcessChangeItem();
17399                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17400                }
17401                item.changes = 0;
17402                item.pid = app.pid;
17403                item.uid = app.info.uid;
17404                if (mPendingProcessChanges.size() == 0) {
17405                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17406                            "*** Enqueueing dispatch processes changed!");
17407                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17408                }
17409                mPendingProcessChanges.add(item);
17410            }
17411            item.changes |= changes;
17412            item.processState = app.repProcState;
17413            item.foregroundActivities = app.repForegroundActivities;
17414            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17415                    + Integer.toHexString(System.identityHashCode(item))
17416                    + " " + app.toShortString() + ": changes=" + item.changes
17417                    + " procState=" + item.processState
17418                    + " foreground=" + item.foregroundActivities
17419                    + " type=" + app.adjType + " source=" + app.adjSource
17420                    + " target=" + app.adjTarget);
17421        }
17422
17423        return success;
17424    }
17425
17426    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17427        if (proc.thread != null) {
17428            if (proc.baseProcessTracker != null) {
17429                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17430            }
17431            if (proc.repProcState >= 0) {
17432                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17433                        proc.repProcState);
17434            }
17435        }
17436    }
17437
17438    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17439            ProcessRecord TOP_APP, boolean doingAll, long now) {
17440        if (app.thread == null) {
17441            return false;
17442        }
17443
17444        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17445
17446        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17447    }
17448
17449    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17450            boolean oomAdj) {
17451        if (isForeground != proc.foregroundServices) {
17452            proc.foregroundServices = isForeground;
17453            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17454                    proc.info.uid);
17455            if (isForeground) {
17456                if (curProcs == null) {
17457                    curProcs = new ArrayList<ProcessRecord>();
17458                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17459                }
17460                if (!curProcs.contains(proc)) {
17461                    curProcs.add(proc);
17462                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17463                            proc.info.packageName, proc.info.uid);
17464                }
17465            } else {
17466                if (curProcs != null) {
17467                    if (curProcs.remove(proc)) {
17468                        mBatteryStatsService.noteEvent(
17469                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17470                                proc.info.packageName, proc.info.uid);
17471                        if (curProcs.size() <= 0) {
17472                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17473                        }
17474                    }
17475                }
17476            }
17477            if (oomAdj) {
17478                updateOomAdjLocked();
17479            }
17480        }
17481    }
17482
17483    private final ActivityRecord resumedAppLocked() {
17484        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17485        String pkg;
17486        int uid;
17487        if (act != null) {
17488            pkg = act.packageName;
17489            uid = act.info.applicationInfo.uid;
17490        } else {
17491            pkg = null;
17492            uid = -1;
17493        }
17494        // Has the UID or resumed package name changed?
17495        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17496                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17497            if (mCurResumedPackage != null) {
17498                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17499                        mCurResumedPackage, mCurResumedUid);
17500            }
17501            mCurResumedPackage = pkg;
17502            mCurResumedUid = uid;
17503            if (mCurResumedPackage != null) {
17504                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17505                        mCurResumedPackage, mCurResumedUid);
17506            }
17507        }
17508        return act;
17509    }
17510
17511    final boolean updateOomAdjLocked(ProcessRecord app) {
17512        final ActivityRecord TOP_ACT = resumedAppLocked();
17513        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17514        final boolean wasCached = app.cached;
17515
17516        mAdjSeq++;
17517
17518        // This is the desired cached adjusment we want to tell it to use.
17519        // If our app is currently cached, we know it, and that is it.  Otherwise,
17520        // we don't know it yet, and it needs to now be cached we will then
17521        // need to do a complete oom adj.
17522        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17523                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17524        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17525                SystemClock.uptimeMillis());
17526        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17527            // Changed to/from cached state, so apps after it in the LRU
17528            // list may also be changed.
17529            updateOomAdjLocked();
17530        }
17531        return success;
17532    }
17533
17534    final void updateOomAdjLocked() {
17535        final ActivityRecord TOP_ACT = resumedAppLocked();
17536        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17537        final long now = SystemClock.uptimeMillis();
17538        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17539        final int N = mLruProcesses.size();
17540
17541        if (false) {
17542            RuntimeException e = new RuntimeException();
17543            e.fillInStackTrace();
17544            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17545        }
17546
17547        mAdjSeq++;
17548        mNewNumServiceProcs = 0;
17549        mNewNumAServiceProcs = 0;
17550
17551        final int emptyProcessLimit;
17552        final int cachedProcessLimit;
17553        if (mProcessLimit <= 0) {
17554            emptyProcessLimit = cachedProcessLimit = 0;
17555        } else if (mProcessLimit == 1) {
17556            emptyProcessLimit = 1;
17557            cachedProcessLimit = 0;
17558        } else {
17559            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17560            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17561        }
17562
17563        // Let's determine how many processes we have running vs.
17564        // how many slots we have for background processes; we may want
17565        // to put multiple processes in a slot of there are enough of
17566        // them.
17567        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17568                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17569        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17570        if (numEmptyProcs > cachedProcessLimit) {
17571            // If there are more empty processes than our limit on cached
17572            // processes, then use the cached process limit for the factor.
17573            // This ensures that the really old empty processes get pushed
17574            // down to the bottom, so if we are running low on memory we will
17575            // have a better chance at keeping around more cached processes
17576            // instead of a gazillion empty processes.
17577            numEmptyProcs = cachedProcessLimit;
17578        }
17579        int emptyFactor = numEmptyProcs/numSlots;
17580        if (emptyFactor < 1) emptyFactor = 1;
17581        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17582        if (cachedFactor < 1) cachedFactor = 1;
17583        int stepCached = 0;
17584        int stepEmpty = 0;
17585        int numCached = 0;
17586        int numEmpty = 0;
17587        int numTrimming = 0;
17588
17589        mNumNonCachedProcs = 0;
17590        mNumCachedHiddenProcs = 0;
17591
17592        // First update the OOM adjustment for each of the
17593        // application processes based on their current state.
17594        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17595        int nextCachedAdj = curCachedAdj+1;
17596        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17597        int nextEmptyAdj = curEmptyAdj+2;
17598        for (int i=N-1; i>=0; i--) {
17599            ProcessRecord app = mLruProcesses.get(i);
17600            if (!app.killedByAm && app.thread != null) {
17601                app.procStateChanged = false;
17602                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17603
17604                // If we haven't yet assigned the final cached adj
17605                // to the process, do that now.
17606                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17607                    switch (app.curProcState) {
17608                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17609                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17610                            // This process is a cached process holding activities...
17611                            // assign it the next cached value for that type, and then
17612                            // step that cached level.
17613                            app.curRawAdj = curCachedAdj;
17614                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17615                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17616                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17617                                    + ")");
17618                            if (curCachedAdj != nextCachedAdj) {
17619                                stepCached++;
17620                                if (stepCached >= cachedFactor) {
17621                                    stepCached = 0;
17622                                    curCachedAdj = nextCachedAdj;
17623                                    nextCachedAdj += 2;
17624                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17625                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17626                                    }
17627                                }
17628                            }
17629                            break;
17630                        default:
17631                            // For everything else, assign next empty cached process
17632                            // level and bump that up.  Note that this means that
17633                            // long-running services that have dropped down to the
17634                            // cached level will be treated as empty (since their process
17635                            // state is still as a service), which is what we want.
17636                            app.curRawAdj = curEmptyAdj;
17637                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17638                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17639                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17640                                    + ")");
17641                            if (curEmptyAdj != nextEmptyAdj) {
17642                                stepEmpty++;
17643                                if (stepEmpty >= emptyFactor) {
17644                                    stepEmpty = 0;
17645                                    curEmptyAdj = nextEmptyAdj;
17646                                    nextEmptyAdj += 2;
17647                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17648                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17649                                    }
17650                                }
17651                            }
17652                            break;
17653                    }
17654                }
17655
17656                applyOomAdjLocked(app, TOP_APP, true, now);
17657
17658                // Count the number of process types.
17659                switch (app.curProcState) {
17660                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17661                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17662                        mNumCachedHiddenProcs++;
17663                        numCached++;
17664                        if (numCached > cachedProcessLimit) {
17665                            app.kill("cached #" + numCached, true);
17666                        }
17667                        break;
17668                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17669                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17670                                && app.lastActivityTime < oldTime) {
17671                            app.kill("empty for "
17672                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17673                                    / 1000) + "s", true);
17674                        } else {
17675                            numEmpty++;
17676                            if (numEmpty > emptyProcessLimit) {
17677                                app.kill("empty #" + numEmpty, true);
17678                            }
17679                        }
17680                        break;
17681                    default:
17682                        mNumNonCachedProcs++;
17683                        break;
17684                }
17685
17686                if (app.isolated && app.services.size() <= 0) {
17687                    // If this is an isolated process, and there are no
17688                    // services running in it, then the process is no longer
17689                    // needed.  We agressively kill these because we can by
17690                    // definition not re-use the same process again, and it is
17691                    // good to avoid having whatever code was running in them
17692                    // left sitting around after no longer needed.
17693                    app.kill("isolated not needed", true);
17694                }
17695
17696                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17697                        && !app.killedByAm) {
17698                    numTrimming++;
17699                }
17700            }
17701        }
17702
17703        mNumServiceProcs = mNewNumServiceProcs;
17704
17705        // Now determine the memory trimming level of background processes.
17706        // Unfortunately we need to start at the back of the list to do this
17707        // properly.  We only do this if the number of background apps we
17708        // are managing to keep around is less than half the maximum we desire;
17709        // if we are keeping a good number around, we'll let them use whatever
17710        // memory they want.
17711        final int numCachedAndEmpty = numCached + numEmpty;
17712        int memFactor;
17713        if (numCached <= ProcessList.TRIM_CACHED_APPS
17714                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17715            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17716                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17717            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17718                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17719            } else {
17720                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17721            }
17722        } else {
17723            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17724        }
17725        // We always allow the memory level to go up (better).  We only allow it to go
17726        // down if we are in a state where that is allowed, *and* the total number of processes
17727        // has gone down since last time.
17728        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17729                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17730                + " last=" + mLastNumProcesses);
17731        if (memFactor > mLastMemoryLevel) {
17732            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17733                memFactor = mLastMemoryLevel;
17734                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17735            }
17736        }
17737        mLastMemoryLevel = memFactor;
17738        mLastNumProcesses = mLruProcesses.size();
17739        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17740        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17741        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17742            if (mLowRamStartTime == 0) {
17743                mLowRamStartTime = now;
17744            }
17745            int step = 0;
17746            int fgTrimLevel;
17747            switch (memFactor) {
17748                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17749                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17750                    break;
17751                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17752                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17753                    break;
17754                default:
17755                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17756                    break;
17757            }
17758            int factor = numTrimming/3;
17759            int minFactor = 2;
17760            if (mHomeProcess != null) minFactor++;
17761            if (mPreviousProcess != null) minFactor++;
17762            if (factor < minFactor) factor = minFactor;
17763            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17764            for (int i=N-1; i>=0; i--) {
17765                ProcessRecord app = mLruProcesses.get(i);
17766                if (allChanged || app.procStateChanged) {
17767                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17768                    app.procStateChanged = false;
17769                }
17770                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17771                        && !app.killedByAm) {
17772                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17773                        try {
17774                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17775                                    "Trimming memory of " + app.processName
17776                                    + " to " + curLevel);
17777                            app.thread.scheduleTrimMemory(curLevel);
17778                        } catch (RemoteException e) {
17779                        }
17780                        if (false) {
17781                            // For now we won't do this; our memory trimming seems
17782                            // to be good enough at this point that destroying
17783                            // activities causes more harm than good.
17784                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17785                                    && app != mHomeProcess && app != mPreviousProcess) {
17786                                // Need to do this on its own message because the stack may not
17787                                // be in a consistent state at this point.
17788                                // For these apps we will also finish their activities
17789                                // to help them free memory.
17790                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17791                            }
17792                        }
17793                    }
17794                    app.trimMemoryLevel = curLevel;
17795                    step++;
17796                    if (step >= factor) {
17797                        step = 0;
17798                        switch (curLevel) {
17799                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17800                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17801                                break;
17802                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17803                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17804                                break;
17805                        }
17806                    }
17807                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17808                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17809                            && app.thread != null) {
17810                        try {
17811                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17812                                    "Trimming memory of heavy-weight " + app.processName
17813                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17814                            app.thread.scheduleTrimMemory(
17815                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17816                        } catch (RemoteException e) {
17817                        }
17818                    }
17819                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17820                } else {
17821                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17822                            || app.systemNoUi) && app.pendingUiClean) {
17823                        // If this application is now in the background and it
17824                        // had done UI, then give it the special trim level to
17825                        // have it free UI resources.
17826                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17827                        if (app.trimMemoryLevel < level && app.thread != null) {
17828                            try {
17829                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17830                                        "Trimming memory of bg-ui " + app.processName
17831                                        + " to " + level);
17832                                app.thread.scheduleTrimMemory(level);
17833                            } catch (RemoteException e) {
17834                            }
17835                        }
17836                        app.pendingUiClean = false;
17837                    }
17838                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17839                        try {
17840                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17841                                    "Trimming memory of fg " + app.processName
17842                                    + " to " + fgTrimLevel);
17843                            app.thread.scheduleTrimMemory(fgTrimLevel);
17844                        } catch (RemoteException e) {
17845                        }
17846                    }
17847                    app.trimMemoryLevel = fgTrimLevel;
17848                }
17849            }
17850        } else {
17851            if (mLowRamStartTime != 0) {
17852                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17853                mLowRamStartTime = 0;
17854            }
17855            for (int i=N-1; i>=0; i--) {
17856                ProcessRecord app = mLruProcesses.get(i);
17857                if (allChanged || app.procStateChanged) {
17858                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17859                    app.procStateChanged = false;
17860                }
17861                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17862                        || app.systemNoUi) && app.pendingUiClean) {
17863                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17864                            && app.thread != null) {
17865                        try {
17866                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17867                                    "Trimming memory of ui hidden " + app.processName
17868                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17869                            app.thread.scheduleTrimMemory(
17870                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17871                        } catch (RemoteException e) {
17872                        }
17873                    }
17874                    app.pendingUiClean = false;
17875                }
17876                app.trimMemoryLevel = 0;
17877            }
17878        }
17879
17880        if (mAlwaysFinishActivities) {
17881            // Need to do this on its own message because the stack may not
17882            // be in a consistent state at this point.
17883            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17884        }
17885
17886        if (allChanged) {
17887            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17888        }
17889
17890        if (mProcessStats.shouldWriteNowLocked(now)) {
17891            mHandler.post(new Runnable() {
17892                @Override public void run() {
17893                    synchronized (ActivityManagerService.this) {
17894                        mProcessStats.writeStateAsyncLocked();
17895                    }
17896                }
17897            });
17898        }
17899
17900        if (DEBUG_OOM_ADJ) {
17901            if (false) {
17902                RuntimeException here = new RuntimeException("here");
17903                here.fillInStackTrace();
17904                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17905            } else {
17906                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17907            }
17908        }
17909    }
17910
17911    final void trimApplications() {
17912        synchronized (this) {
17913            int i;
17914
17915            // First remove any unused application processes whose package
17916            // has been removed.
17917            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17918                final ProcessRecord app = mRemovedProcesses.get(i);
17919                if (app.activities.size() == 0
17920                        && app.curReceiver == null && app.services.size() == 0) {
17921                    Slog.i(
17922                        TAG, "Exiting empty application process "
17923                        + app.processName + " ("
17924                        + (app.thread != null ? app.thread.asBinder() : null)
17925                        + ")\n");
17926                    if (app.pid > 0 && app.pid != MY_PID) {
17927                        app.kill("empty", false);
17928                    } else {
17929                        try {
17930                            app.thread.scheduleExit();
17931                        } catch (Exception e) {
17932                            // Ignore exceptions.
17933                        }
17934                    }
17935                    cleanUpApplicationRecordLocked(app, false, true, -1);
17936                    mRemovedProcesses.remove(i);
17937
17938                    if (app.persistent) {
17939                        addAppLocked(app.info, false, null /* ABI override */);
17940                    }
17941                }
17942            }
17943
17944            // Now update the oom adj for all processes.
17945            updateOomAdjLocked();
17946        }
17947    }
17948
17949    /** This method sends the specified signal to each of the persistent apps */
17950    public void signalPersistentProcesses(int sig) throws RemoteException {
17951        if (sig != Process.SIGNAL_USR1) {
17952            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17953        }
17954
17955        synchronized (this) {
17956            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17957                    != PackageManager.PERMISSION_GRANTED) {
17958                throw new SecurityException("Requires permission "
17959                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17960            }
17961
17962            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17963                ProcessRecord r = mLruProcesses.get(i);
17964                if (r.thread != null && r.persistent) {
17965                    Process.sendSignal(r.pid, sig);
17966                }
17967            }
17968        }
17969    }
17970
17971    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17972        if (proc == null || proc == mProfileProc) {
17973            proc = mProfileProc;
17974            profileType = mProfileType;
17975            clearProfilerLocked();
17976        }
17977        if (proc == null) {
17978            return;
17979        }
17980        try {
17981            proc.thread.profilerControl(false, null, profileType);
17982        } catch (RemoteException e) {
17983            throw new IllegalStateException("Process disappeared");
17984        }
17985    }
17986
17987    private void clearProfilerLocked() {
17988        if (mProfileFd != null) {
17989            try {
17990                mProfileFd.close();
17991            } catch (IOException e) {
17992            }
17993        }
17994        mProfileApp = null;
17995        mProfileProc = null;
17996        mProfileFile = null;
17997        mProfileType = 0;
17998        mAutoStopProfiler = false;
17999        mSamplingInterval = 0;
18000    }
18001
18002    public boolean profileControl(String process, int userId, boolean start,
18003            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18004
18005        try {
18006            synchronized (this) {
18007                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18008                // its own permission.
18009                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18010                        != PackageManager.PERMISSION_GRANTED) {
18011                    throw new SecurityException("Requires permission "
18012                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18013                }
18014
18015                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18016                    throw new IllegalArgumentException("null profile info or fd");
18017                }
18018
18019                ProcessRecord proc = null;
18020                if (process != null) {
18021                    proc = findProcessLocked(process, userId, "profileControl");
18022                }
18023
18024                if (start && (proc == null || proc.thread == null)) {
18025                    throw new IllegalArgumentException("Unknown process: " + process);
18026                }
18027
18028                if (start) {
18029                    stopProfilerLocked(null, 0);
18030                    setProfileApp(proc.info, proc.processName, profilerInfo);
18031                    mProfileProc = proc;
18032                    mProfileType = profileType;
18033                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18034                    try {
18035                        fd = fd.dup();
18036                    } catch (IOException e) {
18037                        fd = null;
18038                    }
18039                    profilerInfo.profileFd = fd;
18040                    proc.thread.profilerControl(start, profilerInfo, profileType);
18041                    fd = null;
18042                    mProfileFd = null;
18043                } else {
18044                    stopProfilerLocked(proc, profileType);
18045                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18046                        try {
18047                            profilerInfo.profileFd.close();
18048                        } catch (IOException e) {
18049                        }
18050                    }
18051                }
18052
18053                return true;
18054            }
18055        } catch (RemoteException e) {
18056            throw new IllegalStateException("Process disappeared");
18057        } finally {
18058            if (profilerInfo != null && profilerInfo.profileFd != null) {
18059                try {
18060                    profilerInfo.profileFd.close();
18061                } catch (IOException e) {
18062                }
18063            }
18064        }
18065    }
18066
18067    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18068        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18069                userId, true, ALLOW_FULL_ONLY, callName, null);
18070        ProcessRecord proc = null;
18071        try {
18072            int pid = Integer.parseInt(process);
18073            synchronized (mPidsSelfLocked) {
18074                proc = mPidsSelfLocked.get(pid);
18075            }
18076        } catch (NumberFormatException e) {
18077        }
18078
18079        if (proc == null) {
18080            ArrayMap<String, SparseArray<ProcessRecord>> all
18081                    = mProcessNames.getMap();
18082            SparseArray<ProcessRecord> procs = all.get(process);
18083            if (procs != null && procs.size() > 0) {
18084                proc = procs.valueAt(0);
18085                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18086                    for (int i=1; i<procs.size(); i++) {
18087                        ProcessRecord thisProc = procs.valueAt(i);
18088                        if (thisProc.userId == userId) {
18089                            proc = thisProc;
18090                            break;
18091                        }
18092                    }
18093                }
18094            }
18095        }
18096
18097        return proc;
18098    }
18099
18100    public boolean dumpHeap(String process, int userId, boolean managed,
18101            String path, ParcelFileDescriptor fd) throws RemoteException {
18102
18103        try {
18104            synchronized (this) {
18105                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18106                // its own permission (same as profileControl).
18107                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18108                        != PackageManager.PERMISSION_GRANTED) {
18109                    throw new SecurityException("Requires permission "
18110                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18111                }
18112
18113                if (fd == null) {
18114                    throw new IllegalArgumentException("null fd");
18115                }
18116
18117                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18118                if (proc == null || proc.thread == null) {
18119                    throw new IllegalArgumentException("Unknown process: " + process);
18120                }
18121
18122                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18123                if (!isDebuggable) {
18124                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18125                        throw new SecurityException("Process not debuggable: " + proc);
18126                    }
18127                }
18128
18129                proc.thread.dumpHeap(managed, path, fd);
18130                fd = null;
18131                return true;
18132            }
18133        } catch (RemoteException e) {
18134            throw new IllegalStateException("Process disappeared");
18135        } finally {
18136            if (fd != null) {
18137                try {
18138                    fd.close();
18139                } catch (IOException e) {
18140                }
18141            }
18142        }
18143    }
18144
18145    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18146    public void monitor() {
18147        synchronized (this) { }
18148    }
18149
18150    void onCoreSettingsChange(Bundle settings) {
18151        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18152            ProcessRecord processRecord = mLruProcesses.get(i);
18153            try {
18154                if (processRecord.thread != null) {
18155                    processRecord.thread.setCoreSettings(settings);
18156                }
18157            } catch (RemoteException re) {
18158                /* ignore */
18159            }
18160        }
18161    }
18162
18163    // Multi-user methods
18164
18165    /**
18166     * Start user, if its not already running, but don't bring it to foreground.
18167     */
18168    @Override
18169    public boolean startUserInBackground(final int userId) {
18170        return startUser(userId, /* foreground */ false);
18171    }
18172
18173    /**
18174     * Start user, if its not already running, and bring it to foreground.
18175     */
18176    boolean startUserInForeground(final int userId, Dialog dlg) {
18177        boolean result = startUser(userId, /* foreground */ true);
18178        dlg.dismiss();
18179        return result;
18180    }
18181
18182    /**
18183     * Refreshes the list of users related to the current user when either a
18184     * user switch happens or when a new related user is started in the
18185     * background.
18186     */
18187    private void updateCurrentProfileIdsLocked() {
18188        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18189                mCurrentUserId, false /* enabledOnly */);
18190        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18191        for (int i = 0; i < currentProfileIds.length; i++) {
18192            currentProfileIds[i] = profiles.get(i).id;
18193        }
18194        mCurrentProfileIds = currentProfileIds;
18195
18196        synchronized (mUserProfileGroupIdsSelfLocked) {
18197            mUserProfileGroupIdsSelfLocked.clear();
18198            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18199            for (int i = 0; i < users.size(); i++) {
18200                UserInfo user = users.get(i);
18201                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18202                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18203                }
18204            }
18205        }
18206    }
18207
18208    private Set getProfileIdsLocked(int userId) {
18209        Set userIds = new HashSet<Integer>();
18210        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18211                userId, false /* enabledOnly */);
18212        for (UserInfo user : profiles) {
18213            userIds.add(Integer.valueOf(user.id));
18214        }
18215        return userIds;
18216    }
18217
18218    @Override
18219    public boolean switchUser(final int userId) {
18220        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18221        String userName;
18222        synchronized (this) {
18223            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18224            if (userInfo == null) {
18225                Slog.w(TAG, "No user info for user #" + userId);
18226                return false;
18227            }
18228            if (userInfo.isManagedProfile()) {
18229                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18230                return false;
18231            }
18232            userName = userInfo.name;
18233            mTargetUserId = userId;
18234        }
18235        mHandler.removeMessages(START_USER_SWITCH_MSG);
18236        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18237        return true;
18238    }
18239
18240    private void showUserSwitchDialog(int userId, String userName) {
18241        // The dialog will show and then initiate the user switch by calling startUserInForeground
18242        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18243                true /* above system */);
18244        d.show();
18245    }
18246
18247    private boolean startUser(final int userId, final boolean foreground) {
18248        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18249                != PackageManager.PERMISSION_GRANTED) {
18250            String msg = "Permission Denial: switchUser() from pid="
18251                    + Binder.getCallingPid()
18252                    + ", uid=" + Binder.getCallingUid()
18253                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18254            Slog.w(TAG, msg);
18255            throw new SecurityException(msg);
18256        }
18257
18258        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18259
18260        final long ident = Binder.clearCallingIdentity();
18261        try {
18262            synchronized (this) {
18263                final int oldUserId = mCurrentUserId;
18264                if (oldUserId == userId) {
18265                    return true;
18266                }
18267
18268                mStackSupervisor.setLockTaskModeLocked(null, false);
18269
18270                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18271                if (userInfo == null) {
18272                    Slog.w(TAG, "No user info for user #" + userId);
18273                    return false;
18274                }
18275                if (foreground && userInfo.isManagedProfile()) {
18276                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18277                    return false;
18278                }
18279
18280                if (foreground) {
18281                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18282                            R.anim.screen_user_enter);
18283                }
18284
18285                boolean needStart = false;
18286
18287                // If the user we are switching to is not currently started, then
18288                // we need to start it now.
18289                if (mStartedUsers.get(userId) == null) {
18290                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18291                    updateStartedUserArrayLocked();
18292                    needStart = true;
18293                }
18294
18295                final Integer userIdInt = Integer.valueOf(userId);
18296                mUserLru.remove(userIdInt);
18297                mUserLru.add(userIdInt);
18298
18299                if (foreground) {
18300                    mCurrentUserId = userId;
18301                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18302                    updateCurrentProfileIdsLocked();
18303                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18304                    // Once the internal notion of the active user has switched, we lock the device
18305                    // with the option to show the user switcher on the keyguard.
18306                    mWindowManager.lockNow(null);
18307                } else {
18308                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18309                    updateCurrentProfileIdsLocked();
18310                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18311                    mUserLru.remove(currentUserIdInt);
18312                    mUserLru.add(currentUserIdInt);
18313                }
18314
18315                final UserStartedState uss = mStartedUsers.get(userId);
18316
18317                // Make sure user is in the started state.  If it is currently
18318                // stopping, we need to knock that off.
18319                if (uss.mState == UserStartedState.STATE_STOPPING) {
18320                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18321                    // so we can just fairly silently bring the user back from
18322                    // the almost-dead.
18323                    uss.mState = UserStartedState.STATE_RUNNING;
18324                    updateStartedUserArrayLocked();
18325                    needStart = true;
18326                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18327                    // This means ACTION_SHUTDOWN has been sent, so we will
18328                    // need to treat this as a new boot of the user.
18329                    uss.mState = UserStartedState.STATE_BOOTING;
18330                    updateStartedUserArrayLocked();
18331                    needStart = true;
18332                }
18333
18334                if (uss.mState == UserStartedState.STATE_BOOTING) {
18335                    // Booting up a new user, need to tell system services about it.
18336                    // Note that this is on the same handler as scheduling of broadcasts,
18337                    // which is important because it needs to go first.
18338                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18339                }
18340
18341                if (foreground) {
18342                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18343                            oldUserId));
18344                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18345                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18346                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18347                            oldUserId, userId, uss));
18348                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18349                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18350                }
18351
18352                if (needStart) {
18353                    // Send USER_STARTED broadcast
18354                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18355                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18356                            | Intent.FLAG_RECEIVER_FOREGROUND);
18357                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18358                    broadcastIntentLocked(null, null, intent,
18359                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18360                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18361                }
18362
18363                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18364                    if (userId != UserHandle.USER_OWNER) {
18365                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18366                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18367                        broadcastIntentLocked(null, null, intent, null,
18368                                new IIntentReceiver.Stub() {
18369                                    public void performReceive(Intent intent, int resultCode,
18370                                            String data, Bundle extras, boolean ordered,
18371                                            boolean sticky, int sendingUser) {
18372                                        onUserInitialized(uss, foreground, oldUserId, userId);
18373                                    }
18374                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18375                                true, false, MY_PID, Process.SYSTEM_UID,
18376                                userId);
18377                        uss.initializing = true;
18378                    } else {
18379                        getUserManagerLocked().makeInitialized(userInfo.id);
18380                    }
18381                }
18382
18383                if (foreground) {
18384                    if (!uss.initializing) {
18385                        moveUserToForeground(uss, oldUserId, userId);
18386                    }
18387                } else {
18388                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18389                }
18390
18391                if (needStart) {
18392                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18393                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18394                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18395                    broadcastIntentLocked(null, null, intent,
18396                            null, new IIntentReceiver.Stub() {
18397                                @Override
18398                                public void performReceive(Intent intent, int resultCode, String data,
18399                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18400                                        throws RemoteException {
18401                                }
18402                            }, 0, null, null,
18403                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18404                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18405                }
18406            }
18407        } finally {
18408            Binder.restoreCallingIdentity(ident);
18409        }
18410
18411        return true;
18412    }
18413
18414    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18415        long ident = Binder.clearCallingIdentity();
18416        try {
18417            Intent intent;
18418            if (oldUserId >= 0) {
18419                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18420                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18421                int count = profiles.size();
18422                for (int i = 0; i < count; i++) {
18423                    int profileUserId = profiles.get(i).id;
18424                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18425                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18426                            | Intent.FLAG_RECEIVER_FOREGROUND);
18427                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18428                    broadcastIntentLocked(null, null, intent,
18429                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18430                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18431                }
18432            }
18433            if (newUserId >= 0) {
18434                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18435                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18436                int count = profiles.size();
18437                for (int i = 0; i < count; i++) {
18438                    int profileUserId = profiles.get(i).id;
18439                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18440                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18441                            | Intent.FLAG_RECEIVER_FOREGROUND);
18442                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18443                    broadcastIntentLocked(null, null, intent,
18444                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18445                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18446                }
18447                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18448                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18449                        | Intent.FLAG_RECEIVER_FOREGROUND);
18450                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18451                broadcastIntentLocked(null, null, intent,
18452                        null, null, 0, null, null,
18453                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18454                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18455            }
18456        } finally {
18457            Binder.restoreCallingIdentity(ident);
18458        }
18459    }
18460
18461    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18462            final int newUserId) {
18463        final int N = mUserSwitchObservers.beginBroadcast();
18464        if (N > 0) {
18465            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18466                int mCount = 0;
18467                @Override
18468                public void sendResult(Bundle data) throws RemoteException {
18469                    synchronized (ActivityManagerService.this) {
18470                        if (mCurUserSwitchCallback == this) {
18471                            mCount++;
18472                            if (mCount == N) {
18473                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18474                            }
18475                        }
18476                    }
18477                }
18478            };
18479            synchronized (this) {
18480                uss.switching = true;
18481                mCurUserSwitchCallback = callback;
18482            }
18483            for (int i=0; i<N; i++) {
18484                try {
18485                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18486                            newUserId, callback);
18487                } catch (RemoteException e) {
18488                }
18489            }
18490        } else {
18491            synchronized (this) {
18492                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18493            }
18494        }
18495        mUserSwitchObservers.finishBroadcast();
18496    }
18497
18498    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18499        synchronized (this) {
18500            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18501            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18502        }
18503    }
18504
18505    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18506        mCurUserSwitchCallback = null;
18507        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18508        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18509                oldUserId, newUserId, uss));
18510    }
18511
18512    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18513        synchronized (this) {
18514            if (foreground) {
18515                moveUserToForeground(uss, oldUserId, newUserId);
18516            }
18517        }
18518
18519        completeSwitchAndInitalize(uss, newUserId, true, false);
18520    }
18521
18522    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18523        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18524        if (homeInFront) {
18525            startHomeActivityLocked(newUserId);
18526        } else {
18527            mStackSupervisor.resumeTopActivitiesLocked();
18528        }
18529        EventLogTags.writeAmSwitchUser(newUserId);
18530        getUserManagerLocked().userForeground(newUserId);
18531        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18532    }
18533
18534    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18535        completeSwitchAndInitalize(uss, newUserId, false, true);
18536    }
18537
18538    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18539            boolean clearInitializing, boolean clearSwitching) {
18540        boolean unfrozen = false;
18541        synchronized (this) {
18542            if (clearInitializing) {
18543                uss.initializing = false;
18544                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18545            }
18546            if (clearSwitching) {
18547                uss.switching = false;
18548            }
18549            if (!uss.switching && !uss.initializing) {
18550                mWindowManager.stopFreezingScreen();
18551                unfrozen = true;
18552            }
18553        }
18554        if (unfrozen) {
18555            final int N = mUserSwitchObservers.beginBroadcast();
18556            for (int i=0; i<N; i++) {
18557                try {
18558                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18559                } catch (RemoteException e) {
18560                }
18561            }
18562            mUserSwitchObservers.finishBroadcast();
18563        }
18564    }
18565
18566    void scheduleStartProfilesLocked() {
18567        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18568            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18569                    DateUtils.SECOND_IN_MILLIS);
18570        }
18571    }
18572
18573    void startProfilesLocked() {
18574        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18575        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18576                mCurrentUserId, false /* enabledOnly */);
18577        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18578        for (UserInfo user : profiles) {
18579            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18580                    && user.id != mCurrentUserId) {
18581                toStart.add(user);
18582            }
18583        }
18584        final int n = toStart.size();
18585        int i = 0;
18586        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18587            startUserInBackground(toStart.get(i).id);
18588        }
18589        if (i < n) {
18590            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18591        }
18592    }
18593
18594    void finishUserBoot(UserStartedState uss) {
18595        synchronized (this) {
18596            if (uss.mState == UserStartedState.STATE_BOOTING
18597                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18598                uss.mState = UserStartedState.STATE_RUNNING;
18599                final int userId = uss.mHandle.getIdentifier();
18600                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18601                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18602                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18603                broadcastIntentLocked(null, null, intent,
18604                        null, null, 0, null, null,
18605                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18606                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18607            }
18608        }
18609    }
18610
18611    void finishUserSwitch(UserStartedState uss) {
18612        synchronized (this) {
18613            finishUserBoot(uss);
18614
18615            startProfilesLocked();
18616
18617            int num = mUserLru.size();
18618            int i = 0;
18619            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18620                Integer oldUserId = mUserLru.get(i);
18621                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18622                if (oldUss == null) {
18623                    // Shouldn't happen, but be sane if it does.
18624                    mUserLru.remove(i);
18625                    num--;
18626                    continue;
18627                }
18628                if (oldUss.mState == UserStartedState.STATE_STOPPING
18629                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18630                    // This user is already stopping, doesn't count.
18631                    num--;
18632                    i++;
18633                    continue;
18634                }
18635                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18636                    // Owner and current can't be stopped, but count as running.
18637                    i++;
18638                    continue;
18639                }
18640                // This is a user to be stopped.
18641                stopUserLocked(oldUserId, null);
18642                num--;
18643                i++;
18644            }
18645        }
18646    }
18647
18648    @Override
18649    public int stopUser(final int userId, final IStopUserCallback callback) {
18650        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18651                != PackageManager.PERMISSION_GRANTED) {
18652            String msg = "Permission Denial: switchUser() from pid="
18653                    + Binder.getCallingPid()
18654                    + ", uid=" + Binder.getCallingUid()
18655                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18656            Slog.w(TAG, msg);
18657            throw new SecurityException(msg);
18658        }
18659        if (userId <= 0) {
18660            throw new IllegalArgumentException("Can't stop primary user " + userId);
18661        }
18662        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18663        synchronized (this) {
18664            return stopUserLocked(userId, callback);
18665        }
18666    }
18667
18668    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18669        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18670        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18671            return ActivityManager.USER_OP_IS_CURRENT;
18672        }
18673
18674        final UserStartedState uss = mStartedUsers.get(userId);
18675        if (uss == null) {
18676            // User is not started, nothing to do...  but we do need to
18677            // callback if requested.
18678            if (callback != null) {
18679                mHandler.post(new Runnable() {
18680                    @Override
18681                    public void run() {
18682                        try {
18683                            callback.userStopped(userId);
18684                        } catch (RemoteException e) {
18685                        }
18686                    }
18687                });
18688            }
18689            return ActivityManager.USER_OP_SUCCESS;
18690        }
18691
18692        if (callback != null) {
18693            uss.mStopCallbacks.add(callback);
18694        }
18695
18696        if (uss.mState != UserStartedState.STATE_STOPPING
18697                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18698            uss.mState = UserStartedState.STATE_STOPPING;
18699            updateStartedUserArrayLocked();
18700
18701            long ident = Binder.clearCallingIdentity();
18702            try {
18703                // We are going to broadcast ACTION_USER_STOPPING and then
18704                // once that is done send a final ACTION_SHUTDOWN and then
18705                // stop the user.
18706                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18707                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18708                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18709                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18710                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18711                // This is the result receiver for the final shutdown broadcast.
18712                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18713                    @Override
18714                    public void performReceive(Intent intent, int resultCode, String data,
18715                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18716                        finishUserStop(uss);
18717                    }
18718                };
18719                // This is the result receiver for the initial stopping broadcast.
18720                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18721                    @Override
18722                    public void performReceive(Intent intent, int resultCode, String data,
18723                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18724                        // On to the next.
18725                        synchronized (ActivityManagerService.this) {
18726                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18727                                // Whoops, we are being started back up.  Abort, abort!
18728                                return;
18729                            }
18730                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18731                        }
18732                        mBatteryStatsService.noteEvent(
18733                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18734                                Integer.toString(userId), userId);
18735                        mSystemServiceManager.stopUser(userId);
18736                        broadcastIntentLocked(null, null, shutdownIntent,
18737                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18738                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18739                    }
18740                };
18741                // Kick things off.
18742                broadcastIntentLocked(null, null, stoppingIntent,
18743                        null, stoppingReceiver, 0, null, null,
18744                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18745                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18746            } finally {
18747                Binder.restoreCallingIdentity(ident);
18748            }
18749        }
18750
18751        return ActivityManager.USER_OP_SUCCESS;
18752    }
18753
18754    void finishUserStop(UserStartedState uss) {
18755        final int userId = uss.mHandle.getIdentifier();
18756        boolean stopped;
18757        ArrayList<IStopUserCallback> callbacks;
18758        synchronized (this) {
18759            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18760            if (mStartedUsers.get(userId) != uss) {
18761                stopped = false;
18762            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18763                stopped = false;
18764            } else {
18765                stopped = true;
18766                // User can no longer run.
18767                mStartedUsers.remove(userId);
18768                mUserLru.remove(Integer.valueOf(userId));
18769                updateStartedUserArrayLocked();
18770
18771                // Clean up all state and processes associated with the user.
18772                // Kill all the processes for the user.
18773                forceStopUserLocked(userId, "finish user");
18774            }
18775
18776            // Explicitly remove the old information in mRecentTasks.
18777            removeRecentTasksForUserLocked(userId);
18778        }
18779
18780        for (int i=0; i<callbacks.size(); i++) {
18781            try {
18782                if (stopped) callbacks.get(i).userStopped(userId);
18783                else callbacks.get(i).userStopAborted(userId);
18784            } catch (RemoteException e) {
18785            }
18786        }
18787
18788        if (stopped) {
18789            mSystemServiceManager.cleanupUser(userId);
18790            synchronized (this) {
18791                mStackSupervisor.removeUserLocked(userId);
18792            }
18793        }
18794    }
18795
18796    @Override
18797    public UserInfo getCurrentUser() {
18798        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18799                != PackageManager.PERMISSION_GRANTED) && (
18800                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18801                != PackageManager.PERMISSION_GRANTED)) {
18802            String msg = "Permission Denial: getCurrentUser() from pid="
18803                    + Binder.getCallingPid()
18804                    + ", uid=" + Binder.getCallingUid()
18805                    + " requires " + INTERACT_ACROSS_USERS;
18806            Slog.w(TAG, msg);
18807            throw new SecurityException(msg);
18808        }
18809        synchronized (this) {
18810            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18811            return getUserManagerLocked().getUserInfo(userId);
18812        }
18813    }
18814
18815    int getCurrentUserIdLocked() {
18816        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18817    }
18818
18819    @Override
18820    public boolean isUserRunning(int userId, boolean orStopped) {
18821        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18822                != PackageManager.PERMISSION_GRANTED) {
18823            String msg = "Permission Denial: isUserRunning() from pid="
18824                    + Binder.getCallingPid()
18825                    + ", uid=" + Binder.getCallingUid()
18826                    + " requires " + INTERACT_ACROSS_USERS;
18827            Slog.w(TAG, msg);
18828            throw new SecurityException(msg);
18829        }
18830        synchronized (this) {
18831            return isUserRunningLocked(userId, orStopped);
18832        }
18833    }
18834
18835    boolean isUserRunningLocked(int userId, boolean orStopped) {
18836        UserStartedState state = mStartedUsers.get(userId);
18837        if (state == null) {
18838            return false;
18839        }
18840        if (orStopped) {
18841            return true;
18842        }
18843        return state.mState != UserStartedState.STATE_STOPPING
18844                && state.mState != UserStartedState.STATE_SHUTDOWN;
18845    }
18846
18847    @Override
18848    public int[] getRunningUserIds() {
18849        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18850                != PackageManager.PERMISSION_GRANTED) {
18851            String msg = "Permission Denial: isUserRunning() from pid="
18852                    + Binder.getCallingPid()
18853                    + ", uid=" + Binder.getCallingUid()
18854                    + " requires " + INTERACT_ACROSS_USERS;
18855            Slog.w(TAG, msg);
18856            throw new SecurityException(msg);
18857        }
18858        synchronized (this) {
18859            return mStartedUserArray;
18860        }
18861    }
18862
18863    private void updateStartedUserArrayLocked() {
18864        int num = 0;
18865        for (int i=0; i<mStartedUsers.size();  i++) {
18866            UserStartedState uss = mStartedUsers.valueAt(i);
18867            // This list does not include stopping users.
18868            if (uss.mState != UserStartedState.STATE_STOPPING
18869                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18870                num++;
18871            }
18872        }
18873        mStartedUserArray = new int[num];
18874        num = 0;
18875        for (int i=0; i<mStartedUsers.size();  i++) {
18876            UserStartedState uss = mStartedUsers.valueAt(i);
18877            if (uss.mState != UserStartedState.STATE_STOPPING
18878                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18879                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18880                num++;
18881            }
18882        }
18883    }
18884
18885    @Override
18886    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18887        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18888                != PackageManager.PERMISSION_GRANTED) {
18889            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18890                    + Binder.getCallingPid()
18891                    + ", uid=" + Binder.getCallingUid()
18892                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18893            Slog.w(TAG, msg);
18894            throw new SecurityException(msg);
18895        }
18896
18897        mUserSwitchObservers.register(observer);
18898    }
18899
18900    @Override
18901    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18902        mUserSwitchObservers.unregister(observer);
18903    }
18904
18905    private boolean userExists(int userId) {
18906        if (userId == 0) {
18907            return true;
18908        }
18909        UserManagerService ums = getUserManagerLocked();
18910        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18911    }
18912
18913    int[] getUsersLocked() {
18914        UserManagerService ums = getUserManagerLocked();
18915        return ums != null ? ums.getUserIds() : new int[] { 0 };
18916    }
18917
18918    UserManagerService getUserManagerLocked() {
18919        if (mUserManager == null) {
18920            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18921            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18922        }
18923        return mUserManager;
18924    }
18925
18926    private int applyUserId(int uid, int userId) {
18927        return UserHandle.getUid(userId, uid);
18928    }
18929
18930    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18931        if (info == null) return null;
18932        ApplicationInfo newInfo = new ApplicationInfo(info);
18933        newInfo.uid = applyUserId(info.uid, userId);
18934        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18935                + info.packageName;
18936        return newInfo;
18937    }
18938
18939    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18940        if (aInfo == null
18941                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18942            return aInfo;
18943        }
18944
18945        ActivityInfo info = new ActivityInfo(aInfo);
18946        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18947        return info;
18948    }
18949
18950    private final class LocalService extends ActivityManagerInternal {
18951        @Override
18952        public void goingToSleep() {
18953            ActivityManagerService.this.goingToSleep();
18954        }
18955
18956        @Override
18957        public void wakingUp() {
18958            ActivityManagerService.this.wakingUp();
18959        }
18960
18961        @Override
18962        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18963                String processName, String abiOverride, int uid, Runnable crashHandler) {
18964            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18965                    processName, abiOverride, uid, crashHandler);
18966        }
18967    }
18968
18969    /**
18970     * An implementation of IAppTask, that allows an app to manage its own tasks via
18971     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18972     * only the process that calls getAppTasks() can call the AppTask methods.
18973     */
18974    class AppTaskImpl extends IAppTask.Stub {
18975        private int mTaskId;
18976        private int mCallingUid;
18977
18978        public AppTaskImpl(int taskId, int callingUid) {
18979            mTaskId = taskId;
18980            mCallingUid = callingUid;
18981        }
18982
18983        private void checkCaller() {
18984            if (mCallingUid != Binder.getCallingUid()) {
18985                throw new SecurityException("Caller " + mCallingUid
18986                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18987            }
18988        }
18989
18990        @Override
18991        public void finishAndRemoveTask() {
18992            checkCaller();
18993
18994            synchronized (ActivityManagerService.this) {
18995                long origId = Binder.clearCallingIdentity();
18996                try {
18997                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18998                    if (tr == null) {
18999                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19000                    }
19001                    // Only kill the process if we are not a new document
19002                    int flags = tr.getBaseIntent().getFlags();
19003                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19004                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19005                    removeTaskByIdLocked(mTaskId,
19006                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19007                } finally {
19008                    Binder.restoreCallingIdentity(origId);
19009                }
19010            }
19011        }
19012
19013        @Override
19014        public ActivityManager.RecentTaskInfo getTaskInfo() {
19015            checkCaller();
19016
19017            synchronized (ActivityManagerService.this) {
19018                long origId = Binder.clearCallingIdentity();
19019                try {
19020                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19021                    if (tr == null) {
19022                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19023                    }
19024                    return createRecentTaskInfoFromTaskRecord(tr);
19025                } finally {
19026                    Binder.restoreCallingIdentity(origId);
19027                }
19028            }
19029        }
19030
19031        @Override
19032        public void moveToFront() {
19033            checkCaller();
19034
19035            final TaskRecord tr;
19036            synchronized (ActivityManagerService.this) {
19037                tr = recentTaskForIdLocked(mTaskId);
19038                if (tr == null) {
19039                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19040                }
19041                if (tr.getRootActivity() != null) {
19042                    moveTaskToFrontLocked(tr.taskId, 0, null);
19043                    return;
19044                }
19045            }
19046
19047            startActivityFromRecentsInner(tr.taskId, null);
19048        }
19049
19050        @Override
19051        public int startActivity(IBinder whoThread, String callingPackage,
19052                Intent intent, String resolvedType, Bundle options) {
19053            checkCaller();
19054
19055            int callingUser = UserHandle.getCallingUserId();
19056            TaskRecord tr;
19057            IApplicationThread appThread;
19058            synchronized (ActivityManagerService.this) {
19059                tr = recentTaskForIdLocked(mTaskId);
19060                if (tr == null) {
19061                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19062                }
19063                appThread = ApplicationThreadNative.asInterface(whoThread);
19064                if (appThread == null) {
19065                    throw new IllegalArgumentException("Bad app thread " + appThread);
19066                }
19067            }
19068            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19069                    resolvedType, null, null, null, null, 0, 0, null, null,
19070                    null, options, callingUser, null, tr);
19071        }
19072
19073        @Override
19074        public void setExcludeFromRecents(boolean exclude) {
19075            checkCaller();
19076
19077            synchronized (ActivityManagerService.this) {
19078                long origId = Binder.clearCallingIdentity();
19079                try {
19080                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19081                    if (tr == null) {
19082                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19083                    }
19084                    Intent intent = tr.getBaseIntent();
19085                    if (exclude) {
19086                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19087                    } else {
19088                        intent.setFlags(intent.getFlags()
19089                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19090                    }
19091                } finally {
19092                    Binder.restoreCallingIdentity(origId);
19093                }
19094            }
19095        }
19096    }
19097}
19098